SpringBoot 配置 Servlet、Filter、Listener

SpringBoot 的嵌入式 Servlet 容器不支持 ServletContainerInitializer 和 WebApplicationInitializer,以减少第三方库对应用的影响。推荐使用 ServletContextInitializer 接口进行初始化配置。在 Spring Boot 应用中,可以注册 ServletContextInitializer 的实现来初始化 Servlet、Filter 和 Listener。ServletRegistrationBean、ServletListenerRegistrationBean 以及 AbstractFilterRegistrationBean 提供了动态注册这些组件的能力,即使打包成 war 并部署到 Tomcat 也有效。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

嵌入式的 Servlet 3.0+ 容器不会直接使用 ServletContainerInitializer 和 WebApplicationInitializer,即通过以上两个接口实现的(Servlet、Filter、Listener)配置是无效的,这是为了防止第三方代码的设计损坏应用程序,原文如下

Embedded servlet containers will not directly execute the Servlet 3.0+ javax.servlet.ServletContainerInitializer interface, or Spring’s org.springframework.web.WebApplicationInitializer interface. This is an intentional design decision intended to reduce the risk that 3rd party libraries designed to run inside a war will break Spring Boot applications.

If you need to perform servlet context initialization in a Spring Boot application, you should register a bean that implements the org.springframework.boot.context.embedded.ServletContextInitializer interface. The single onStartup method provides access to the ServletContext, and can easily be used as an adapter to an existing WebApplicationInitializer if necessary.

由上可知,我们可以使用替代方案:ServletContextInitializer

@Configuration
public class GoServletContextInitializer implements ServletContextInitializer {

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {

        //Log4j Config Listener  
        servletContext.setInitParameter("log4jConfigLocation", "classpath:config/properties/log4j.properties");  
        servletContext.addListener(Log4jConfigListener.class);  


        //CharacterEncodingFilter
        FilterRegistration.Dynamic characterEncodingFilter =
                servletContext.addFilter("characterEncodingFilter", CharacterEncodingFilter.class);
        characterEncodingFilter.setInitParameter("encoding", "UTF-8");
        characterEncodingFilter.setInitParameter("forceEncoding", "true");
        characterEncodingFilter.addMappingForUrlPatterns(
                EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD, DispatcherType.INCLUDE),
                false, "/*");


        //statViewServlet  
        StatViewServlet statViewServlet = new StatViewServlet();
        ServletRegistration.Dynamic dynamic = servletContext.addServlet(
                "statViewServlet", statViewServlet);
        dynamic.setLoadOnStartup(2);
        dynamic.addMapping("/druid/*");
    }
}

亲测,即使将 Spring Boot 打包成 war,并部署到 Tomcat 8.5,这份配置也是有效的


第二种方案:ServletContextInitializer 的延伸

请看继承体系

这里写图片描述
位于最下边的三个类都能实现运行时注册(Servlet、Listener、Filter):
1. ServletRegistrationBean 在系统初始化时向 ServletContext 注册其包含的一个 Servlet,我们可以事先设置它的 Servlet,再把它定义为一个 Bean
2. ServletListenerRegistrationBean 在系统初始化时向 ServletContext 注册其包含的一个 ServletContextListener,我们可以事先设置它的 Listener,再把它定义为一个 Bean
3. AbstractFilterRegistrationBean 通过抽象模板方法 getFilter(),将构建 Filter 的具体细节开放给子类,而其会在系统初始化时向 ServletContext 注册这个 Filter,对此,我们可以定义一个派生类,重写该模板方法以返回我们需要构建的 Filter,最后把它定义为一个 Bean

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值