Spring Boot webflux 和自动装配

标签:

本文出自jvm123.com-java技术分享站:http://jvm123.com/2019/11/spring-boot-webflux.html

自动装配: 激活自动装配

  1. @EnableAutoConfiguration
  2. 配置 /META-INF/spring.factories
  3. 实现 XXXAutoConfiguration

org.springframework.boot.autoconfigure

Auto Configure 自动装配

spring.factories 文件的内容如下:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,
org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,
org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\

autoconfigure模块中定义了如上许多自动装配的类。在springboot启动时,会根据这些类进行装配组件。由于mvn依赖的不同,会导致一部分XxxAutoConfiguration上的注解条件满足,如果满足,则会检查XxxAutoConfiguration中装配bean组件的条件,如果条件也满足,就会装配这个bean。

将springboot打包成war包:

将springboot打包成war包,可以对项目进行以下的修改:

  1. 将pom.xml中的<packaging> 改为 war。
  2. 然后在src/main/ 目录下增加文件 /WEB-INF/web.xml 文件,文件内容可以为空即可。
  3. 执行mvn package后,生成 *.war 文件,
  4. 可以放在tomcat等容器下部署,也可以直接使用java -jar *.war 运行,效果与jar包相同。

Reactive web webflux:

Spring Boot webflux 和自动装配插图

spring-boot-starter-webflux 提供函数式的 web API,并且能够自动发现RouterFunction beans。所以我们的应用程序有两种方式使用Webflux:RouterFunction or RequestMapping 。示例如下:

1 RequestMapping  方式:

	@GetMapping("/user")
	Flux<User> list() {
		Iterable<User> users = this.userRepos.findAll();
		return Flux.fromIterable(users);
	}

2 RouterFunction 方式:

ServerRequest、ServerResponse相当于HttpServletRequest和HttpServletResponse。

使用RouterFunctions.route实例化一个RouterFunctions需要两个参数:第一个为RequestPredicate,表明哪些请求可以被路由;第二个参数是HandlerFunction<ServerResponse>,用于处理请求。HandlerFunction类似于@controller注解的类,用于处理请求。

HandlerFunction<ServerResponse>需要实现hanlde方法,这个方法通过处理ServerRequest,返回一个Mono<ServerResponse>。可以通过ServerRequest获得请求相关的信息,并进行处理;生成ServerResponse,需要Publisher,即FluxorMono

  • Flux (0…N): 0~N个对象的stream 
  • Mono (0 or 1): 0或1个对象的stream,类似于Option
import com.jvm123.demo.entity.User;
import com.jvm123.demo.repos.UserRepos;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.function.server.HandlerFunction;
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 org.springframework.web.reactive.function.server.ServerRequest;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.web.reactive.function.server.RequestPredicates.*;

/**
 * @author yawn http://jvm123.com
 * 2019/11/7 15:52
 */
@Configuration
public class RouterFunctionsConfig {


    @Autowired
    private UserRepos userRepos;

    /**
     * HttpServletRequest、HttpServletResponse
     * ServerRequest、ServerResponse (spring 5.0)
     * Flux、Mono都是Publisher,发射器,将数据发送出去
     */
    @Bean
    public RouterFunction<ServerResponse> routerFunction() {
        RouterFunction<ServerResponse> userRoute =
                RouterFunctions.route(
                        GET("/route/user").and(accept(APPLICATION_JSON)),
                        new HandlerFunction<ServerResponse>() {
                            @Override
                            public Mono<ServerResponse> handle(ServerRequest request) {
                                request.queryParams().forEach((name, value) -> System.out.println(name + "=" + value));
                                Iterable<User> users = userRepos.findAll();
                                Flux<User> userFlux = Flux.fromIterable(users);
                                // Flux\Mono都是Publisher,发射器,将数据发送出去
                                return ServerResponse.ok().body(userFlux, User.class);
                            }
                        }
                );

        return userRoute;
    }
}

发表评论