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

1. 问题:使用@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的代理对象。

2. springboot中创建filter方式

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

1.1 @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,

1.2 使用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;
    }

1.3 使用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;
    }

遇到个坑: myFilter中没有重写init方法, 导致打成war包之后放到tomcat8中怎么也起不来,springboot中启动没问题, 不明原因。

1.4 将自定义Filter声明为bean,Spring初始化时自动注册

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值