嵌入式web容器

支持三种容器:Tomcat Jetty Undertow
springboot2.x的重大更新之一,就是支持响应式web server(1.x只支持servlet web容器)

一、 更改容器配置
方式1:
在application.properties中设置,形如:

  1. server.port=8090
  2. #localhost:8090/duing
  3. server.servlet.context-path=/duing
  4. server.tomcat.max-connections=5000

方式2:
创建自定义器,实现WebServerFactoryCustomizer的customize方法,可以设置端口号等 (优先级高于配置文件)

  1. package com.duing.config;
  2. import org.springframework.boot.web.server.ConfigurableWebServerFactory;
  3. import org.springframework.boot.web.server.WebServerFactoryCustomizer;
  4. import org.springframework.context.annotation.Bean;
  5. import org.springframework.context.annotation.Configuration;
  6. @Configuration
  7. public class WebConfig {
  8. @Bean
  9. public WebServerFactoryCustomizer<ConfigurableWebServerFactory> customizer(){
  10. return new WebServerFactoryCustomizer<ConfigurableWebServerFactory>() {
  11. @Override
  12. public void customize(ConfigurableWebServerFactory factory) {
  13. factory.setPort(8899);
  14. }
  15. };
  16. }
  17. }

二、更改使用容器
从starter-web中移除starter-tomcat,引入新的容器启动器

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-web</artifactId>
  4. <exclusions>
  5. <exclusion>
  6. <groupId>org.springframework.boot</groupId>
  7. <artifactId>spring-boot-starter-tomcat</artifactId>
  8. </exclusion>
  9. </exclusions>
  10. </dependency>
  11. <dependency>
  12. <groupId>org.springframework.boot</groupId>
  13. <artifactId>spring-boot-starter-jetty</artifactId>
  14. </dependency>

三、使用响应式web容器
去掉对starter-web的引用,增加starter-webflux(两者同时存在时,还会使用servlet容器)

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-undertow</artifactId>
  4. </dependency>
  5. <dependency>
  6. <groupId>org.springframework.boot</groupId>
  7. <artifactId>spring-boot-starter-webflux</artifactId>
  8. </dependency>

编写一个响应式编程的demo

  1. package com.duing;
  2. import org.springframework.boot.SpringApplication;
  3. import org.springframework.boot.autoconfigure.SpringBootApplication;
  4. import org.springframework.context.annotation.Bean;
  5. import org.springframework.web.reactive.function.server.RouterFunction;
  6. import org.springframework.web.reactive.function.server.ServerResponse;
  7. import reactor.core.publisher.Mono;
  8. import static org.springframework.web.reactive.function.server.RequestPredicates.GET;
  9. import static org.springframework.web.reactive.function.server.RouterFunctions.route;
  10. import static org.springframework.web.reactive.function.server.ServerResponse.ok;
  11. @SpringBootApplication
  12. public class WebContainerApplication {
  13. public static void main(String[] args) {
  14. SpringApplication.run(WebContainerApplication.class, args);
  15. }
  16. @Bean
  17. public RouterFunction<ServerResponse> hello(){
  18. return route(GET("/hello"),
  19. serverRequest -> ok().body(
  20. Mono.just("Hello world"),String.class));
  21. }
  22. }

image.png

四、查看web应用启动类
方式一
通过WebServerApplicationContext容器获取类名,在容器启动后回调使用 (当前应用为web应用时可用)

@Bean
    public ApplicationRunner runner(WebServerApplicationContext context){
        return args -> {
            System.out.println("当前容器的实现类为:"+context.getWebServer().getClass().getName());
        };
    }

方式二
通过监听WebServerInitializedEvent初始化事件,在容器启动前触发

package com.duing.config;

import org.springframework.boot.web.context.WebServerInitializedEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;

@Component
public class ListenerConfig {

    @EventListener(WebServerInitializedEvent.class)
    public void onWebServerReady(WebServerInitializedEvent event){
        System.out.println("当前容器的实现类是:"+
                event.getWebServer().getClass().getName());
    }
}

image.png
image.png