SpringBoot(17)之Servlet容器配置与三大组件的注册

SpringBoot(17)之Servlet容器配置与三大组件的注册

微信搜索 zze_coding 或扫描 👉 二维码关注我的微信公众号获取更多资源推送:

SpringBoot 默认使用的嵌入式 Servlet 容器为 Tomcat,通过依赖关系就可以看到:

image.png

问题:

  • 如何定制和修改 Servlet 容器相关配置?
  • SpringBoot 能否支持其它 Servlet 容器?

配置 Servlet 容器

配置文件

在普通 Web 程序中我们如果需要修改 Tomcat 配置则可通过 Tomcat 目录下 conf/server.xml 修改,而在 SpringBoot 中我们只需要在项目配置文件中通过 server 节下的相关属性即可修改容器相关配置,如:

# 通用 Servlet 容器配置
server.port=8080
server.context-path=/
# Tomcat 配置
server.tomcat.uri-encoding=utf-8

容器的定制器

除了上述配置的方式,SpringBoot 还为我们提供了嵌入式 Servlet 容器的定制器类来定制相关配置,例:

@Bean
public EmbeddedServletContainerCustomizer embeddedServletContainerCustomizer(){
    return new EmbeddedServletContainerCustomizer() {
        // 定制嵌入式 Servlet 容器相关规则
        @Override
        public void customize(ConfigurableEmbeddedServletContainer container) {
            // container 即为容器对象
            container.setPort(8088);
        }
    };
}

配置文件中 server 节对应的配置属性类内部也是通过该方式定义容器配置的。

三大组件的注册

如果是在一个标准的 Web 工程中,我们可以通过 WEB-INF/web.xml 来注册三大组件,即 Servlet、Filter、Listener。而 SpringBoot 项目默认是以 jar 包的方式通过嵌入式的 Servlet 容器来启动 web 应用,没有 web.xml,注册三大组件则需要按照以下方式:

注册 Servlet-ServletRegistrationBean

@Bean
public ServletRegistrationBean myServlet(){
    return new ServletRegistrationBean(new MyServlet(), "/servlet/hello");
}

注册 Filter-FilterRegistrationBean

@Bean
public FilterRegistrationBean myFilter(){
    FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
    filterRegistrationBean.setFilter(new MyFilter());
    filterRegistrationBean.setUrlPatterns(Arrays.asList("/servlet/hello","/login"));
    return filterRegistrationBean;
}

注册 Listener-ListenerRegistrationBean

@Bean
public ServletListenerRegistrationBean myListener(){
    return new ServletListenerRegistrationBean(new MyListener());
}

SpringMVC 的核心 Servlet 在 SpringBoot 中就是以此种方式注册,如下:

// org.springframework.boot.autoconfigure.web.DispatcherServletAutoConfiguration
@Bean(name = DEFAULT_DISPATCHER_SERVLET_BEAN_NAME)
public DispatcherServlet dispatcherServlet() {
    DispatcherServlet dispatcherServlet = new DispatcherServlet();
    dispatcherServlet.setDispatchOptionsRequest(
            this.webMvcProperties.isDispatchOptionsRequest());
    dispatcherServlet.setDispatchTraceRequest(
            this.webMvcProperties.isDispatchTraceRequest());
    dispatcherServlet.setThrowExceptionIfNoHandlerFound(
            this.webMvcProperties.isThrowExceptionIfNoHandlerFound());
    return dispatcherServlet;
}

    @Configuration
    @Conditional(DispatcherServletRegistrationCondition.class)
    @ConditionalOnClass(ServletRegistration.class)
    @EnableConfigurationProperties(WebMvcProperties.class)
    @Import(DispatcherServletConfiguration.class)
    protected static class DispatcherServletRegistrationConfiguration {

        private final ServerProperties serverProperties;

        private final WebMvcProperties webMvcProperties;

        private final MultipartConfigElement multipartConfig;

        public DispatcherServletRegistrationConfiguration(
                ServerProperties serverProperties, WebMvcProperties webMvcProperties,
                ObjectProvider<MultipartConfigElement> multipartConfigProvider) {
            this.serverProperties = serverProperties;
            this.webMvcProperties = webMvcProperties;
            this.multipartConfig = multipartConfigProvider.getIfAvailable();
        }

        @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());
            registration.setName(DEFAULT_DISPATCHER_SERVLET_BEAN_NAME);
            registration.setLoadOnStartup(
                    this.webMvcProperties.getServlet().getLoadOnStartup());
            if (this.multipartConfig != null) {
                registration.setMultipartConfig(this.multipartConfig);
            }
            return registration;
        }

}

Copyright: 采用 知识共享署名4.0 国际许可协议进行许可

Links: https://www.zze.xyz/archives/springboot17.html

Buy me a cup of coffee ☕.