在过滤器中的doFilterInternal写业务代码时,需要用到spring bean组件,发现在过滤器中无法初始化bean组件,均为NullPointerException,经检查 扫描包路径没问题。最终确定容器加载顺序引发的问题。在web.xml中各个元素的执行顺序是这样的,context-param-->listener-->filter-->servlet 可以看出在Spring MVC 的dispatcherservlet初始化之前过滤器就已经加载好了,所以注入的是null。
红箭头标注的均为null对象
解决思路是doFilterInternal使用spring上下文取获取相应的bean组件,对于Spring Boot我们可以使用一下步骤来解决
第一步:创建上下文工具类SpringContextUtil
1 import org.springframework.context.ApplicationContext; 2 3 public class SpringContextUtil { 4 5 private static ApplicationContext applicationContext; 6 7 //获取上下文 8 public static ApplicationContext getApplicationContext() { 9 return applicationContext; 10 } 11 12 //设置上下文 13 public static void setApplicationContext(ApplicationContext applicationContext) { 14 SpringContextUtil.applicationContext = applicationContext; 15 } 16 17 //通过名字获取上下文中的bean 18 public static Object getBean(String name){ 19 return applicationContext.getBean(name); 20 } 21 22 //通过类型获取上下文中的bean 23 public static Object getBean(Class<?> requiredType){ 24 return applicationContext.getBean(requiredType); 25 } 26 27 }
第二步:在Springboot启动类的main方法中,向上下文工具类SpringContextUtil中注入applicationContext
1 public static void main(String[] args) throws InterruptedException { 2 ApplicationContext context = SpringApplication.run(Application.class, args); 3 SpringContextUtil.setApplicationContext(context); 4 }
第三步:在相应的业务代码中 使用SpringContextUtil.getBean("xxx") 获取相应的bean组件即可,如:
1 JwtUtil jwtUtil = (JwtUtil) SpringContextUtil.getBean("jwtUtil"); 2 UserLogMapper userLogMapper = (UserLogMapper) SpringContextUtil.getBean("userLogMapper"); 3 JedisServer jedisServer = (JedisServer) SpringContextUtil.getBean("jedisServerImpl");
经检查:空指针问题解决。