Springboot Filter中注入bean无效为null问题
作者:l梁晴
Springboot Filter注入bean无效为null问题
问题原因
Web应用的启动顺序是:
Lisenter->Fliter->Servlet
应用程序上下文, 初始化 Fliter的时候,
还没有初始化Servlert
所有没有进入DispacterServlet的初始化
故在Fliter中使用注解注入bean为空;
解决办法
添加初始化bean配置,手动创建对象new
代码如下:
package com.test.config;
import com.alibaba.druid.support.http.StatViewServlet;
import com.test.service.RequestFilter;
import javax.servlet.Filter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.filter.DelegatingFilterProxy;
/**
* @author lucasliang
* @date 08/11/2018 5:56 afternoon filter load before dispathServlet ,so load RequestFilter as a
* bean,new a RequestFilter
*/
@Configuration
public class FilterConfig {
/*
*@param: []
*@return javax.servlet.Filter
*@author lucasliang
*@date 20/12/2018
*@Description filter
*/
@Bean
public Filter uploadFilter() {
return new RequestFilter();
}
/*
*@param: []
*@return org.springframework.boot.web.servlet.FilterRegistrationBean
*@author lucasliang
*@date 20/12/2018
*@Description filter
*/
@Bean
@SuppressWarnings("unchecked")
public FilterRegistrationBean testFilterRegistration() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(new DelegatingFilterProxy("uploadFilter"));
registration.addUrlPatterns("/*");
registration.addInitParameter("paramName", "paramValue");
registration.setName("testFilter");
registration.setOrder(1);
registration.setEnabled(false);
return registration;
}
}其中RequestFilter是手动创建的bean
实现了Filter接口
package com.test.service;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
public class RequestFilter implements Filter {
private Logger logger = LoggerFactory.getLogger(Filter.class);
@Value(value = "${encodeRules}")
private String encodeRules;
}此时,在RequestFilter中使用@Value注解,就可以取到值了,注入bean也相同,会取到对应的bean。
至此问题解决!
关于Spring中,注入的bean为null的情况
描述问题
在写项目的时候,写了一个工具类或者测试类,然后调用相关的service层或者dao层的bean,但是通通为null,为啥呢?
问题原因
两种情况会导致如此问题,一个是工具类中的方法为静态方法,静态方法调用了bean,但是由于spring的加载机制,是加载静态代码-》构造函数-》注入bean-》postconstuct的顺序执行,因此静态方法里调用的bean,并没有注入相应的bean,因此为空,所以会出现bean为null的情况。
另一种情况是,调用工具类的时候,new了一个工具类的实例,该应用里的实例都是交给spring IOC容器去看管维护的,现在突然new出来一个实例,spring IOC容器是没有去看管他的,所以并不在同一个上下文中,那么new出来的这个类里面的实例方法,当然也调用不到spring IOC上下文里的实例了,所以当你调用你new出来的实例的方法时候,该方法里调用的spring的bean,都是没有注入的对象的。
如何解决
解决办法同样有两种,针对上面说的第一个问题的解决办法是,使用注解@postconstruct的方法,手动注入bean,因为postconstruct的方法,在bean加载完成之后,init之前执行,所以在这个时间点,注入相应的bean对象,就会生效。
第二种方法是,直接把该工具类作为spring的一个bean组件,使用@component,在业务层调用的时候,也同样使用注入的方式注入该工具类,这样也可以解决问题了。
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
