简介
Spring WebFlux 是 Spring Framework 5.0中引入的新的响应式web框架。与Spring MVC不同,它不需要Servlet API,是完全异步且非阻塞的,并且通过Reactor项目实现了Reactive Streams规范。Spring WebFlux 用于创建基于事件循环执行模型的完全异步且非阻塞的应用程序。
【spring-webmvc + Servlet + Tomcat】命令式的、同步阻塞的
【spring-webflux + Reactor + Netty】响应式的、异步非阻塞的
因此在webflux中平时所用的例如数据库中间件都不跟平时常用的servlet+tomcat这套命令式、同步阻塞的不同。
数据库
在日常开发中使用最多的就是连接数据库,在响应式、异步阻塞的模式中需要使用专门的组件为r2dbc,使用起来很方便。maven中添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-r2dbc</artifactId>
<version>2.5.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.github.jasync-sql/jasync-r2dbc-mysql -->
<dependency>
<groupId>com.github.jasync-sql</groupId>
<artifactId>jasync-r2dbc-mysql</artifactId>
<version>1.2.2</version>
</dependency>
连接mysql则还需要单独导入支持响应式的mysql derive 这里用的是jasync,因为是spring-boot-starter,所以只需要在配置文件中加入以下配置:
r2dbc:
url: mysql://%s:%s@rm-xxxx.mysql.rds.aliyuncs.com/database
username: xxxx
password: xxxxxxx
pool:
enabled: true
initial-size: 100
max-size: 200
max-idle-time: 30m
validation-query: SELECT 1
很奇怪自动装配不能自动的装配数据库的账号及密码,因此需要手动注入
@Configuration
public class MysqlConfig {
@Value("${spring.r2dbc.url}")
private String url;
@Value("${spring.r2dbc.username}")
private String username;
@Value("${spring.r2dbc.password}")
private String password;
@Bean
public R2dbcEntityTemplate r2dbcEntityTemplate(ConnectionFactory connectionFactory) {
return new R2dbcEntityTemplate(connectionFactory);
}
@Bean
public ConnectionFactory connectionFactory() {
com.github.jasync.sql.db.Configuration configuration = URLParser.INSTANCE.parseOrDie(String.format(url, username, password), StandardCharsets.UTF_8);
return new JasyncConnectionFactory(new MySQLConnectionFactory(configuration));
}
}
将数据库的账号及密码从url传入。然后通过jasync的工厂构建数据库的链接工厂。
其他用法上r2dbc与传统的spring-data-jpa类似
定义实体类:
@Data
@Builder
@Table("demo_user")
public class DemoUser {
@Id
private Long id;
private String name;
private Integer gender;
private LocalDateTime updateTime;
private LocalDateTime createTime;
}
定义repository:
public interface DemoUserRepository extends ReactiveCrudRepository<DemoUser,Long> {
<S extends T> Mono<S> save(S entity);
/**
* Saves all given entities.
*
* @param entities must not be {@literal null}.
* @return {@link Flux} emitting the saved entities.
* @throws IllegalArgumentException in case the given {@link Iterable entities} or one of its entities is
* {@literal null}.
*/
<S extends T> Flux<S> saveAll(Iterable<S> entities);
/**
* Saves all given entities.
*
* @param entityStream must not be {@literal null}.
* @return {@link Flux} emitting the saved entities.
* @throws IllegalArgumentException in case the given {@link Publisher entityStream} is {@literal null}.
*/
<S extends T> Flux<S> saveAll(Publisher<S> entityStream);
}
直接继承ReactiveCrudRepository接口,该接口中已经定义好了一些基本的增删改查方法,与传统的命令式编程的区别是返回结果是有响应式编程中特有的Mono或Flux包装的,需要注意的就是需要加上以下注解reository才会生效
@EnableR2dbcRepositories(basePackages = "com.xxx.repository")
然后就像spring-data-jpa一样使用就行
private final DemoUserRepository userRepository;
@GetMapping("/users")
public Flux<AiFunction> getUser(){
return userRepository.findAll();
}
当然也可以自定义sql
@Query("select * from demo_user where name = :name")
Mono<AiFunction> findByUserName(String name);
未完待续。。。