華納發行 10 萬份《黑客帝國 4:矩陣重生》主題 NFT 頭像,單個售價約 320 元
阿新 • • 發佈:2021-11-03
目錄
什麼是Spring Webflux
Spring Webflux是 Spring5 新增新的模組,用於 web 開發的,功能和 SpringMVC 類似的,Webflux 使用當前一種比較流程響應式程式設計出現的框架。
響應式程式設計
響應式程式設計是一種面向資料流和變化傳播的程式設計正規化。這意味著可以在程式語言中很方便地表達靜態或動態的資料流,而相關的計算模型會自動將變化的值通過資料流進行傳播。
反應式 API
與Spring Mvc不同
SpringMVC 採用指令式程式設計,Webflux 採用非同步響應式程式設計
核心控制器
實現方式
Spring Webflux 實現方式有兩種:註解程式設計模型和函數語言程式設計模型
註解程式設計模型
//資料庫表 /* Navicat Premium Data Transfer Source Server : school Source Server Type : MySQL Source Server Version : 80022 Source Host : localhost:3306 Source Schema : school Target Server Type : MySQL Target Server Version : 80022 File Encoding : 65001 Date: 08/11/2021 22:10:28 */ SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0; -- ---------------------------- -- Table structure for grade -- ---------------------------- DROP TABLE IF EXISTS `grade`; CREATE TABLE `grade` ( `gradeId` int(0) NOT NULL AUTO_INCREMENT, `gradeName` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL, PRIMARY KEY (`gradeId`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8 COLLATE = utf8_bin ROW_FORMAT = Dynamic; -- ---------------------------- -- Records of grade -- ---------------------------- INSERT INTO `grade` VALUES (1, 'S1'); INSERT INTO `grade` VALUES (2, 'Y1'); SET FOREIGN_KEY_CHECKS = 1;
//pom檔案 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-webflux</artifactId> <version>2.2.2.RELEASE</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.1.4</version> </dependency>
//application.yml
spring:
datasource:
url: jdbc:mysql://localhost:3306/school?serverTimezone=GMT%2B8
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
mybatis:
mapper-locations: classpath:mapper/*.xml
package com.fly.webflux.entity;
public class Grade {
private Integer gradeId;
private String gradeName;
@Override
public String toString() {
return "Grade{" +
"gradeId=" + gradeId +
", gradeName='" + gradeName + '\'' +
'}';
}
public Integer getGradeId() {
return gradeId;
}
public void setGradeId(Integer gradeId) {
this.gradeId = gradeId;
}
public String getGradeName() {
return gradeName;
}
public void setGradeName(String gradeName) {
this.gradeName = gradeName;
}
}
package com.fly.webflux.dao;
import com.fly.webflux.entity.Grade;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface GradeDao {
Grade getGradeById(Integer gradeId);
List<Grade> getAll();
}
package com.fly.webflux.service;
import com.fly.webflux.entity.Grade;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
public interface GradeService {
Mono<Grade> getGradeById(Integer gradeId);
Flux<Grade> getAll();
}
package com.fly.webflux.service.impl;
import com.fly.webflux.dao.GradeDao;
import com.fly.webflux.entity.Grade;
import com.fly.webflux.service.GradeService;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import javax.annotation.Resource;
@Service
public class GradeServiceImpl implements GradeService {
@Resource
private GradeDao gradeDao;
@Override
public Mono<Grade> getGradeById(Integer gradeId) {
return Mono.justOrEmpty(gradeDao.getGradeById(gradeId));
}
@Override
public Flux<Grade> getAll() {
return Flux.fromIterable(gradeDao.getAll());
}
}
package com.fly.webflux.controller;
import com.fly.webflux.entity.Grade;
import com.fly.webflux.service.GradeService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import javax.annotation.Resource;
@RestController
public class GradeController {
@Resource
private GradeService gradeService;
@GetMapping("/grade/{gradeId}")
public Mono<Grade> getGradeById(@PathVariable Integer gradeId) {
return gradeService.getGradeById(gradeId);
}
@GetMapping("/grade/getall")
public Flux<Grade> getAll() {
return gradeService.getAll();
}
}
函數語言程式設計模型
複製剛才的工程,刪掉controller
package com.fly.webflux.handler;
import com.fly.webflux.entity.Grade;
import com.fly.webflux.service.GradeService;
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
/**
* @author 26414
*/
public class GradeHandler {
private final GradeService gradeService;
public GradeHandler(GradeService gradeService) {
this.gradeService = gradeService;
}
public Mono<ServerResponse> getGradeById(ServerRequest request) {
Integer gradeId = Integer.parseInt(request.pathVariable("id"));
Mono<Grade> grade = gradeService.getGradeById(gradeId);
return
ServerResponse.ok().contentType(MediaType.APPLICATION_JSON).body(grade,Grade.class);
}
//沒有ServerRequest request這個引數設定路由時檢測不到方法
public Mono<ServerResponse> getAll(ServerRequest request) {
Flux<Grade> grades = gradeService.getAll();
return ServerResponse.ok().contentType(MediaType.APPLICATION_JSON).body(grades,Grade.class);
}
}
package com.fly.webflux.service;
import com.fly.webflux.handler.GradeHandler;
import com.fly.webflux.service.impl.GradeServiceImpl;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.HttpHandler;
import org.springframework.http.server.reactive.ReactorHttpHandlerAdapter;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.RouterFunctions;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.netty.http.server.HttpServer;
import java.io.IOException;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.web.reactive.function.server.RequestPredicates.GET;
import static org.springframework.web.reactive.function.server.RequestPredicates.accept;
import static org.springframework.web.reactive.function.server.RouterFunctions.toHttpHandler;
/**
* @author 26414
*/
public class Server {
//建立 Router 路由
public RouterFunction<ServerResponse> routingFunction() {
//建立hanler物件
GradeService gradeService = new GradeServiceImpl();
GradeHandler handler = new GradeHandler(gradeService);
//設定路由
return RouterFunctions.route(
GET("/grade/{id}").and(accept(APPLICATION_JSON)), handler::getGradeById)
.andRoute(GET("/grade/getALl").and(accept(APPLICATION_JSON)),handler::getAll);
}
public void createReactorServer() {
//路由和handler適配
RouterFunction<ServerResponse> route = routingFunction();
HttpHandler httpHandler = toHttpHandler(route);
ReactorHttpHandlerAdapter adapter = new ReactorHttpHandlerAdapter(httpHandler);
//建立伺服器
HttpServer httpServer = HttpServer.create();
httpServer.handle(adapter).bindNow();
}
public static void main(String[] args) throws IOException {
Server server = new Server();
server.createReactorServer();
System.out.println("enter to exit");
System.in.read();
}
}