在Sprint Boot实现Spring WebMVC与WebFlux的比较

18-08-16 banq
              

Spring Boot应用程序可以用命令风格(如传统Spring WebMVC)或函数风格(如Spring WebFlux)编写。下面是使用pring WebFlux两个注意点:

1.目前,spring boot支持Spring WebMVC或WebFlux模型,因此我们不能在一个应用程序中两者混合使用。如果使用pring WebFlux,就不应该使用@RestController注释,并不要在pom.xml中配置spring-boot-starter-web依赖。

2.REST端点应该在@Configuration注释的类上使用, 被定义为RouerFunction的一个Bean,既不是在@RestController注释类,也不是在@Controller注释上使用。

Spring webflux是一种编程范例,可以使用lambda函数风格(声明式风格)组合Spring Boot应用程序。

Spring MVC 和 WebFlux代码比较

让我们看看每个模型上的一些代码,下面写了几个GET / POST / DELETE Rest端点。

实体定义:

@Table
public class Topic {
    @PrimaryKey
    private String topicid;
    private String name;
    private String content;
    private String author;
    private String category;

}
<p>

REST端点在Spring Web-MVC中定义:

@RestController
@RequestMapping(path="/api")
public class BlogControllers {
	@Autowired BlogRepository blogRepository;
	@GetMapping(path="/blogs")
	public Flux<Topic> getAll(){
		return blogRepository.findAll();
	}
	@GetMapping(path="/blogs/{id}")
	public Mono<Topic> getById(@PathVariable("id") String id){
		return blogRepository.findById(id);
	}
	@PostMapping(path="/blogs")
	public Flux<Topic> createBlogs(@RequestBody Flux<Topic> blogs){
		return blogRepository.saveAll(blogs);
	}
	@DeleteMapping
	public Mono<Void> deleteById(@PathVariable("id") String id){
		return blogRepository.deleteById(id);
	}
}
<p>

而在REST端点Spring WebFlux中的代码:

@Configuration
public class BlogRouters {
    @Autowired
    BlogRepository blogRepository;
    @Bean
    public RouterFunction blogroute(){
        return RouterFunctions.nest(RequestPredicates.path("/api"),
                RouterFunctions.route(RequestPredicates.GET("/blogs"),
                        req-> ServerResponse.ok().body(blogRepository.findAll(),Topic.class))
                .andRoute(RequestPredicates.GET("/blogs/id/{id}"),
                        req -> ServerResponse.ok().body(blogRepository.findById(req.pathVariable("id")),Topic.class))
                .andRoute(RequestPredicates.POST("/blogs"),
                        req -> ServerResponse.ok().body(blogRepository.saveAll(req.bodyToFlux(Topic.class)),Topic.class))
                .andRoute(RequestPredicates.DELETE("/blogs/id/{id}"),
                        req -> ServerResponse.ok().body(blogRepository.deleteById(req.pathVariable("id")),Void.class))
        );
    }

}
<p>

少数注释被lambda函数替换,但不是所有的注释,WebFlux是注释和lambda函数的组合。

为了更好地重用可用性/代码结构,我们可以定制一个专用的handler处理程序和utility实用程序类作为Spring组件或服务。

结论

控制器变成为了路由器,请求和响应相关的注释变成为lambda函数,仍然需要注释发挥重要作用,甚至RouterFunction本身也配置了@Configuration和@Bean注释。

我认为,现在Pivotal主导的Spring正朝着基于lambda函数的配置方向发展。(XML→注释→lambda函数)

Sprint boot application using Spring WebMVC and We

              

2