在过滤器中的doFilterInternal写业务代码时,需要用到spring bean组件,发现在过滤器中无法初始化bean组件,均为NullpointException,经检查扫描包路径没问题。最终确定容器加载顺序引发的问题,在web.xml中各个元素的执行顺序是这样的,context-->param-->listener-->filter-->servlet可以看出在spring MVC 的dispatcherServlet初始化之前过滤器就已经加载好了,所以注入的是null。
解决思路是doFilterInternal使用spring上下文取获取相应的bean组件,对于Spring Boot我们可以使用以下步骤来解决
第一步:创建上下文工具类SpringContextUtil
@Component
public class SpringContextUtil implements ApplicationContextAware {
private static ApplicationContext context = null;
//设置上下文
@Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
SpringContextUtil .context = applicationContext;
}
//获取上下文
public static ApplicationContext getApplicationContext(){
return context;
}
// 通过名字获取上下文的Bean
public static <T> T getBean(String beanName) {
return (T) context.getBean(beanName);
}
//通过类型获取上下文的bean
public static <T> T setBean(Class<?> requiredType){
return applicationContext.getBean(requireType);
}
// 国际化使用
public static String getMessage(String key) {
return context.getMessage(key, null, Locale.getDefault());
}
// 获取当前环境
public static String[] getActiveProfiles() {
return context.getEnvironment().getActiveProfiles();
}
// 判断当前环境是否为test/local
public static boolean isDevEnv(){
String[] activeProfiles = getActiveProfiles();
if (activeProfiles.length<1){
return false;
}
for (String activeProfile : activeProfiles) {
if (StringUtils.equals(activeProfile,"dev")){
return true;
}
}
return false;
}
}
第二步:若没有继承ApplicationContextAware ,在Springboot启动类的main方法中,向上下文工具类SpringContextUtil中注入applicationContext
第三步:在相应的业务代码中 使用SpringContextUtil.getBean("xxx") 获取相应的bean组件即可,如: