DelegatingFilterProxy就是一个对于servlet filter的代理,用这个类的好处主要是通过Spring容器来管理servlet filter的生命周期,还有就是如果filter中需要一些Spring容器的实例,可以通过spring直接注入,另外读取一些配置文件这些便利的操作都可以通过Spring来配置实现。
DelegatingFilterProxy运用
需求
在springboot中 使用了filter, 并且注入了业务工具类(APIUtil ),但注入是null
所以问题就来了:springboot中使用filter时注入bean为null的解决办法
其实Spring中,web应用启动的顺序是:listener->filter->servlet,先初始化listener,然后再来就filter的初始化,再接着才到我们的dispathServlet的初始化
解决办法1:
public class TokenAuthFilter implements Filter {
private final static Logger log = LoggerFactory.getLogger(TokenAuthFilter.class);
@Autowired
private APIUtil apiUtil;
}
新增一个config类,用来手工创建filter的bean, 例如:
@Configuration
public class WebConfig {
@Bean
public Filter tokenAuthFilter() {
return new TokenAuthFilter(); //第一步:先将filter放入容器
}
/**
* 注册filter,统一处理api开头的请求
* @return FilterRegistrationBean
*/
@Bean
public FilterRegistrationBean tokenAuthFilterRegistration() {
FilterRegistrationBean registration = new FilterRegistrationBean();
// 第二步:DelegatingFilterProxy把servlet 容器中的filter同spring容器中的bean关联起来
registration.setFilter(new DelegatingFilterProxy("tokenAuthFilter"));
registration.addUrlPatterns("/api/*");
registration.setName("tokenAuthFilter");
registration.setOrder(1);
return registration;
}
}
解决办法2:
过滤器是servlet规范中定义的,并不归spring容器管理,也无法直接注入spring中的bean(会报错)
初始化时通过spring上下文获取,进行bean的初始化:
@Override
public void init(FilterConfig filterConfig) throws ServletException {
ApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(filterConfig.getServletContext());
RedisTemplate demoBean = (RedisTemplate)context.getBean("redisTemplate");
System.out.println(demoBean);
}