控制台 退出登录

springboot项目中使用filter无法注入bean踩坑


springboot项目中使用filter踩坑

问题:使用@WebFilter无法注入bean

问题原因: web容器加载顺序导致, 加载顺序是listener——filter——servlet,当项目启动时,filter先于servlet初始化, 而Spring中默认bean的初始化是在Servlet后进行的,所以会注入失败。

解决方式: 1、 如果是web.xml配置, 可将Spring容器改成Listener方式初始化:org.springframework.web.context.ContextLoaderListener。 2、 使用FilterRegistrationBean或者DelegatingFilterProxyRegistrationBean注册filter, 为什么可以这么实现呢?因为FilterRegistrationBean和DelegatingFilterProxyRegistrationBean都继承了AbstractFilterRegistrationBean抽象类,而该抽象类实现了ServletContextInitializer接口, Spring容器初始化时会遍历查找实现ServletContextInitializer接口的bean,并调用onStartup方法注册自定义的filter。3、将filter声明为bean,Spring容器初始化时也会调用onStartup方法注册filter,但该方式无法定义拦截规则, 默认拦截所有请求。

FilterRegistrationBean和DelegatingFilterProxyRegistrationBean区别:
FilterRegistrationBean通过onStartup方法直接注册filter。
DelegatingFilterProxyRegistrationBean是将DelegatingFilterProxy注册到Servlet3.0+的容器中,同时实现了ApplicationContextAware接口,实例ApplicationContext通过通过传入自定义filter的名称查找对应的bean,并生成相应bean的代理对象。

解决

springboot内嵌tomcat容器, 无法通过web.xml的方式配置filter, 下面是springbot创建filter的几种方式。

@WebFilter注解

注意: 需在启动类添加@ServletComponentScan注解进行扫描

@WebFilter(urlPatterns = "/*", filterName = "myFilter")
@Order(2)
public class MyFilter implements Filter {
 //myService将无法注入
 @Autowired
    private MyService myService;
    
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("MyFilter初始化!");
    }
    
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("进入filter中拦截!");
        servletResponse.getWriter().write("hello world!");
    }
    
    @Override
    public void destroy() {
    }
}

问题: 无法注入bean,

使用FilterRegistrationBean方式

public FilterRegistrationBean filterRegistrationBean(){
        FilterRegistrationBean registrationBean = new FilterRegistrationBean();
        registrationBean.setFilter(new MyFilter);
        registrationBean.addInitParameter("targetFilterLifecycle","true");
        registrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico");
        registrationBean.addUrlPatterns("/*");
        registrationBean.setDispatcherTypes(DispatcherType.REQUEST);
        return registrationBean;
    }

使用DelegatingFilterProxyRegistrationBean方式

public DelegatingFilterProxyRegistrationBean delegatingFilterProxyRegistrationBean(){
        DelegatingFilterProxyRegistrationBean filterProxy = new DelegatingFilterProxyRegistrationBean("myFilter");
        filterProxy.addUrlPatterns("/*");
        filterProxy.addInitParameter("targetFilterLifecycle","true");
        filterProxy.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico");
        filterProxy.setDispatcherTypes(DispatcherType.REQUEST);
        return filterProxy;
    }

本文采用 CC BY-NC-SA 4.0 协议发布

相关文章

None

None

None

None

SpringCloud(9)

SpringCloud(9)

SpringCloud(8)