SpringBoot中添加拦截器,在拦截器中注入其他类的时候出现空指针异常解决办法
程序员文章站
2022-04-16 08:53:37
...
拦截器代码
/**
*
* 记录用户轨迹
*/
@Component
public class AdminInterceptor implements HandlerInterceptor {
@Autowired
SysLogDao sysLogDao
/**
* 在整个请求结束之后被调用,也就是在DispatcherServlet 渲染了对应的视图之后执行(主要是用于进行资源清理工作)
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("执行了AdminInterceptor的afterCompletion方法");
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH-mm-ss");
LocalDateTime now = LocalDateTime.now();
Object user = request.getSession().getAttribute("userName");
Object msg = request.getSession().getAttribute("msg");
if (user != null && msg != null) {
SysLog sysLog = new SysLog();
sysLog.setLogId(IDUtils.getId());
sysLog.setUserName(user.toString());
sysLog.setMsg(msg.toString());
sysLog.setCreateTime(dateTimeFormatter.format(now));
SysLog save = sysLogDao.save(sysLog);
}
}
}
注入拦截器
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
//静态资源:*.css *.js
//Spring Boot 已经做好了静态资源映射
InterceptorRegistration interceptorRegistration = registry.addInterceptor(new AdminInterceptor());
interceptorRegistration.addPathPatterns("/**").excludePathPatterns("/","/login");
}
}
调用接口时发现,SysLogDao 并没有被注入进来!明明代码写的没问题,为什么不能正常注入SysLogDao 呢?
仔细观察我们自定义的配置类WebConfig ,在添加拦截器的时候用的是new AdminInterceptor(),如果想要拦截器生效,必须将拦截器配置到WebMvc的配置类中,就是我们自定义的WebConfig 类。现在添加拦截器的时候是 new 了一个拦截器,也就是说并没有将拦截器托管给IOC容器,拦截器加载是在springcontext创建之前完成的,所以就无法引入Spring的bean对象。
解决办法:让Bean对象提前加载,将拦截器注入进来。
方式一:
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Autowired
public AdminInterceptor adminInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
//静态资源:*.css *.js
//Spring Boot 已经做好了静态资源映射
InterceptorRegistration interceptorRegistration = registry.addInterceptor(adminInterceptor);
interceptorRegistration.addPathPatterns("/**").excludePathPatterns("/","/login");
}
}
方式二:
拦截器无需增加@Component注解,在WebConfiguration类中使用@Bean注解将拦截器注成bean。
/**
*
* 登录检查
* 记录用户轨迹
*/
public class AdminInterceptor implements HandlerInterceptor {
...
}
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Bean
public AdminInterceptor adminInterceptor(){
return new AdminInterceptor();
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
//静态资源:*.css *.js
//Spring Boot 已经做好了静态资源映射
InterceptorRegistration interceptorRegistration = registry.addInterceptor(adminInterceptor());
interceptorRegistration.addPathPatterns("/**").excludePathPatterns("/","/login");
}
}