Bootstrap

Servlet过滤器与Spring整合的通俗拆解:从“水火不容”到“默契搭档”

Servlet过滤器与Spring整合的通俗拆解:从“水火不容”到“默契搭档”

一、引子:当Servlet过滤器遇到Spring容器

想象一个场景:你正在开发一个电商系统,需要在用户下单前通过过滤器验证权限。你发现,过滤器中无法直接使用Spring管理的用户服务(UserService),只能通过笨重的ApplicationContextUtils手动获取Bean。更头疼的是,过滤器的初始化和销毁逻辑写死在init()destroy()中,无法利用Spring的@PostConstruct@PreDestroy优雅管理资源。

这就是典型的问题场景

  1. 依赖注入失效:过滤器由Servlet容器创建,Spring的@Autowired注解形同虚设。
  2. 生命周期割裂:过滤器的初始化和销毁无法与Spring Bean的优雅启停协同工作。

二、破局之道:两种整合方案对比
方案1:中间人代理模式(DelegatingFilterProxy)

角色定位:相当于一个“翻译官”,站在Servlet容器和Spring过滤器之间传递请求。

核心流程(以权限过滤器为例):

  1. Servlet容器初始化阶段

    • Servlet容器发现web.xml中配置了一个DelegatingFilterProxy,名为authFilter
    • 容器调用authFilter.init(),但此时它只是一个“空壳”。
    // web.xml配置
    <filter>
        <filter-name>authFilter</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>
    
  2. Spring容器启动后

    • DelegatingFilterProxy从Spring容器中找到真正的过滤器Bean(如AuthFilter)。
    • 如果设置了targetFilterLifecycle=trueSpring会调用AuthFilter.init()(此时AuthFilter已具备依赖注入能力)。
  3. 请求处理阶段

    • 当用户访问受保护的URL时,Servlet容器调用authFilter.doFilter()
    • DelegatingFilterProxy将请求转交给Spring管理的AuthFilter执行权限校验。
    // Spring管理的真实过滤器
    @Component("authFilter")
    public class AuthFilter implements Filter {
         
        @Autowired // 终于能注入Spring Bean了!
        private UserService userService;
    
        @Override
        public 
;