spring boot配置Servlet容器

Spring boot 默认使用Tomcat作为嵌入式Servlet容器,只需要引入spring-boot-start-web依赖,默认采用的Tomcat作为容器

spring boot配置Servlet容器

01 定制和修改Servlet容器的相关配置(ServerProperties是EmbeddedServletContainerCustomizer的子类)

server.port=8080  
server.context-path=/  
  
# tomcat相关设置  
server.tomcat.uri-encoding=UTF-8

也可以编写EmbeddedServletContainerCustomizer(嵌入式的Servlet容器定制器),来修改servlet容器的配置

@Bean  
public EmbeddedServletContainerCustomizer embeddedServletContainerCustomizer(){  
    //定制嵌入式的Servlet容器相关的属性配置  
    return container -> container.setPort(8083);  
}

2 注册Servlet容器的三大组件(Servlet Filter Listener)

spring boot默认采用是以jar包的形式启动嵌入式的servlet容器,从而启动Springboot的web应用,没有web.xml,当然也可以使用注解的方式(@WebServlet,@WebListener,@WebFilter),现在使用Spring boot作为框架,如果编写三大组件,则需要使用配置的方式进行注册

01 ServletRegistrationBean:注册Servlet

//Servlet定义  
public class MyServlet extends HttpServlet {  
  
    @Override  
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {  
        System.out.println("这是一个servlet请求...");  
    }  
}  
  
//Servlet注册  
@Configuration  
public class MyServletConfig {  
  
    //注册Servlet  
    @Bean  
    public ServletRegistrationBean myServlet(){  
        return new ServletRegistrationBean(new MyServlet(), "/myServlet");  
    }  
}

02 FilterRegistrationBean:注册Filter

//Filter定义  
public class MyFilter implements Filter {  
    @Override  
    public void init(FilterConfig filterConfig) throws ServletException {  
  
    }  
  
    @Override  
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {  
        System.out.println("MyFilter process...");  
        //放行  
        chain.doFilter(request, response);  
    }  
  
    @Override  
    public void destroy() {  
  
    }  
}  
  
//Filter注册  
@Bean  
public FilterRegistrationBean myFilter(){  
    FilterRegistrationBean bean = new FilterRegistrationBean();  
    bean.setFilter(new MyFilter());  
    bean.setUrlPatterns(Arrays.asList("/hello", "/myServlet"));  
    return bean;  
}

ServletListenerRegistrationBean:注册Listener

//Listener定义  
public class MyListener implements ServletContextListener {  
    @Override  
    public void contextInitialized(ServletContextEvent sce) {  
        System.out.println("contextInitialized...web启动");  
    }  
  
    @Override  
    public void contextDestroyed(ServletContextEvent sce) {  
        System.out.println("contextDestroyed...web销毁");  
    }  
}  
  
//Listener注册  
@Bean  
public ServletListenerRegistrationBean myListener(){  
    return new ServletListenerRegistrationBean<>(new MyListener());  
}

最熟悉的是,spring boot 在自动配置springMVC,会自动注册SpringMVC前端控制器:DispatcherServlet,该控制器主要在DispatcherServletAutoConfiguration自动配置类中进行注册

@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)  
@Configuration  
@ConditionalOnWebApplication  
@ConditionalOnClass(DispatcherServlet.class)  
@AutoConfigureAfter(EmbeddedServletContainerAutoConfiguration.class)  
public class DispatcherServletAutoConfiguration {  
      
    //other code...  
      
    public static final String DEFAULT_DISPATCHER_SERVLET_BEAN_NAME = "dispatcherServlet";  
      
    private String servletPath = "/";  
      
    @Bean(name = DEFAULT_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME)  
                @ConditionalOnBean(value = DispatcherServlet.class, name = DEFAULT_DISPATCHER_SERVLET_BEAN_NAME)  
    public ServletRegistrationBean dispatcherServletRegistration(  
        DispatcherServlet dispatcherServlet) {  
        ServletRegistrationBean registration = new ServletRegistrationBean(  
            dispatcherServlet, this.serverProperties.getServletMapping());  
        //默认拦截 / 所有请求,包括静态资源,但是不拦截jsp请求;/*会拦截jsp  
        //可以通过修改server.servlet-path来修改默认的拦截请求  
        registration.setName(DEFAULT_DISPATCHER_SERVLET_BEAN_NAME);  
        registration.setLoadOnStartup(  
            this.webMvcProperties.getServlet().getLoadOnStartup());  
        if (this.multipartConfig != null) {  
            registration.setMultipartConfig(this.multipartConfig);  
        }  
        return registration;  
    }  
}

3 其他Servlet容器

Spring boot默认支持Tomcat,Jetty 和Undertow作为底层容器

spring boot配置Servlet容器

而Spring boot默认使用Tomcat,一旦引入spring-boot-starter-web模块,就默认使用Tomcat

切换其其他Servlet容器

将tomcat依赖移除同事引入其他Servlet容易

引入jetty

<dependency>  
    <groupId>org.springframework.boot</groupId>  
    <artifactId>spring-boot-starter-web</artifactId>  
    <exclusions>  
        <exclusion>  
            <artifactId>spring-boot-starter-tomcat</artifactId>  
            <groupId>org.springframework.boot</groupId>  
        </exclusion>  
    </exclusions>  
</dependency>  
  
<dependency>  
    <groupId>org.springframework.boot</groupId>  
    <artifactId>spring-boot-starter-jetty</artifactId>  
</dependency>

引入undertow

<dependency>  
    <groupId>org.springframework.boot</groupId>  
    <artifactId>spring-boot-starter-web</artifactId>  
    <exclusions>  
        <exclusion>  
            <artifactId>spring-boot-starter-tomcat</artifactId>  
            <groupId>org.springframework.boot</groupId>  
        </exclusion>  
    </exclusions>  
</dependency>  
  
<dependency>  
    <groupId>org.springframework.boot</groupId>  
    <artifactId>spring-boot-starter-jetty</artifactId>  
</dependency>

参考文章 https://blog.csdn.net/caychen/article/details/80344372

这里对于常见的容器jetty和tomcat做一个简单对比

jetty 更轻量级,更加灵活,可插拔和可扩展,其架构是基于Handler来实现的,可以同时处理大量长时间连接,默认采用NIO,在处理静态资源性能较高

Tomcat 默认采用BIO,基于容器设计的,不易扩展,对JavaEE和Servlet的支持更加全面,很多特性直接集成

相关推荐