1.什麼是WebFlux? WebFlux不需要Servlet API,在完全非同步且無阻塞,並通過Reactor項目實現了Reactor Streams規範。 WebFlux可以在資源有限的情況下提高系統的吞吐量和伸縮性。 WebFlux除支持Restful Web服務外,還可以用於提供動態HTML ...
1.什麼是WebFlux?
WebFlux不需要Servlet API,在完全非同步且無阻塞,並通過Reactor項目實現了Reactor Streams規範。
WebFlux可以在資源有限的情況下提高系統的吞吐量和伸縮性。
WebFlux除支持Restful Web服務外,還可以用於提供動態HTML內容。
2.比較MVC和WebFlux
SpringMVC採用命令式編程的方式,代碼被一句一句的執行,便於開發者理解與調試代碼,WebFlux則是基於非同步響應式編程!
1.工作方式
MVC
MVC的工作流程是:主線程接收到請求(request)-> 準備數據 ->返回數據。
整個過程是單線程阻塞的,用戶會感覺等待時間長是因為,在結果處理好之後才會返回結果給瀏覽器。。因此,如果請求過多,則吞吐量會上不去。
WebFlux
工作流程:主線程接收到請求 -> 立刻返回數據與函數的組合 -> 開啟一個新的work線程去做實際的數據準備工作,進行真正的業務操作 -> work線程完成工作 -> 返回用戶真實數據(結果)
這種方式給人的感覺是響應時間很短,因為返回的是不變的常數,它不隨用戶數量的增加而變化!不支持MySql等關係型資料庫。
3/認識Mono和Flux
Mono和Flux屬於事件發佈者,為消費者提供訂閱介面。當有事件發生時,Mono和Flux會回調消費者的相應方法,然後通知消費者相應的事件。
Mono和Flux用於處理非同步數據流,它不像MVC中那樣直接返回String/list,而是將非同步數據流包裝Mono和Flux對象。
Mono和Flux的區別
Mono主要用於返回單個數據,Flux主要用於返回多個數據。
舉例:如果要根據id查詢某個User對象,則返回的肯定是單個User,那麼需要將其包裝成Mono<User>
若需要獲取所有User,則需要將這個集合包裝成Flux<User>.這裡的單個數據並不是指的是一個數據,而是指一個封裝好的對象。多個數據就是多個對象。
開發WebFLux的流程
1.註解式開發流程
WebFLux是響應式框架。地址映射也是通過@RequestMapping提供的,用@Controller和@RestController來代替Handler類。
2.響應式開發流程
1.創建handler類
這裡的handler類相當於SpringMVC的Controller層中的方法體。在響應式編程中,請求和相應不再是HttpServletRequest和HttpServletResponse,而是變成了ServerRequest和ServerResponse。
2.配置RouterFunction
RouterFunction和註解@RequestMapping類似,都用於提供URL路徑。
實例:用註解式開發實現數據的增加,刪除,修改和查詢
首先創建實體類
package com.example.demo.webFlux.entity; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @Data @AllArgsConstructor @NoArgsConstructor public class User { private long id; private String name; private int age; }
然後編寫控制器,實現WebFlux操作數據功能,
package com.example.demo.controller; import com.example.demo.webFlux.entity.User; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import javax.annotation.PostConstruct; import javax.jws.soap.SOAPBinding; import java.util.HashMap; import java.util.Map; import java.util.stream.Collectors; @RestController @RequestMapping(path = "/user") public class UserController { Map<Long, User> users = new HashMap<>(); @PostConstruct public void init() throws Exception{ users.put(Long.valueOf(1),new User(1,"Curry",34)); users.put(Long.valueOf(2),new User(2,"Iverson",44)); } /* * 獲取所有用戶 * */ @GetMapping("/list") public Flux<User> getAll(){ return Flux.fromIterable(users.entrySet().stream().map(entry->entry.getValue()).collect(Collectors.toList())); } /* * 獲取單個用戶 * */ @GetMapping("/{id}") public Mono<User> getUser(@PathVariable Long id){ return Mono.justOrEmpty(users.get(id)); } /* * 創建用戶 * */ @PostMapping("") public Mono<ResponseEntity<String>> addUser(User user){ users.put(user.getId(),user); return Mono.just(new ResponseEntity<>("添加成功", HttpStatus.CREATED)); } /* * 修改用戶 * */ @PutMapping("/{id}") public Mono<ResponseEntity<User>> putUser(@PathVariable Long id,User user){ user.setId(id); users.put(id,user); return Mono.just(new ResponseEntity<>(user,HttpStatus.CREATED)); } /* * 刪除用戶 * */ @DeleteMapping("/{id}") public Mono<ResponseEntity<String>> deleteUser(@PathVariable Long id){ users.remove(id); return Mono.just(new ResponseEntity<>("刪除成功",HttpStatus.ACCEPTED)); } }
最後,啟動項目,看結果
下麵,來通過postman來增添一份數據,
通過put請求可以修改數據