当前reactive编程模式大行其道,Spring WebFlux也跟着流行起来。WebFlux是Spring Recative Stack的核心组件,Spring WebFlux默认使用Netty作为底层网络组件,同时也支持将tomcat、jetty等java应用服务嵌入到Spring中使用。
但现在还是有很多公司在使用WebSphere、WebLogic、Jboss等传统的JavaEE应用服务器,如何让这些JavaEE应用服务器也能使用Spring WebFlux,并享受到reactive编程模式的乐趣,将是本文的主要内容。
要想让JavaEE应用服务器支持Spring WebFlux,它们必须先要支持Servlet3.1,Servlet3.1中包含两个重要的功能:
1.异步(通过javax.servlet.AsyncContext实现)
2.非阻塞IO(通过javax.servlet.ReadListener、javax.servlet.WriteListener实现)
如果以前使用的框架中用到的是spring-mvc,则需要将其中的spring-mvc替换成spring-webflux::
下面介绍一下具体的配置和代码
pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.5.7</version>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
<version>2.5.7</version>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-reactor-netty</artifactId>
</exclusion>
</exclusions>
</dependency>
1.spring-boot-starter-web中将默认带的tomcat和spring-webmvc都排除掉
2.spring-boot-starter-webflux中将默认带的netty排除掉
java代码
@EnableWebFlux
@SpringBootApplication(exclude = { TaskSchedulingAutoConfiguration.class, ErrorMvcAutoConfiguration.class })
public class WebApp extends AbstractReactiveWebInitializer {
public static void main(String[] args) {
ConfigurableApplicationContext ctx = SpringApplication.run(WebApp.class, args);
ctx.registerShutdownHook();
}
@Override
protected Class<?>[] getConfigClasses() {
Class<?>[] clazz = { WebConfig.class };
return clazz;
}
}
需要定义一个WebHandler
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.DispatcherHandler;
import org.springframework.web.server.WebHandler;
@Configuration
@ComponentScan
public class WebConfig {
@Bean
public WebHandler webHandler(ApplicationContext applicationContext) {
return new DispatcherHandler(applicationContext);
}
}
可以定义一个Controller处理所有请求
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class WebController {
@RequestMapping(path = "/**")
public String doTest() {
String body = "time:" + DateTimeFormatter.ISO_LOCAL_DATE_TIME.format(LocalDateTime.now());
return body;
}
}
但以上方法不能使用springboot的配置文件,比如application.properties、application.yaml等。可以通过在WebApp中添加如下方法实现这个功能:
protected ApplicationContext createApplicationContext() {
AnnotationConfigReactiveWebApplicationContext context = new AnnotationConfigReactiveWebApplicationContext();
ConfigDataEnvironmentPostProcessor.applyTo(context.getEnvironment());
Class<?>[] configClasses = getConfigClasses();
Assert.notEmpty(configClasses, "No Spring configuration provided through getConfigClasses()");
context.register(configClasses);
return context;
}
一个简单的使用Spring WebFlux实现Reactive模式的例子就完成了。以上代码为了测试方便,也可以放在tomcat或jetty等实现了servlet3.1规范的Java容器中运行。