正常的拦截类,注入了User。
1 2 3 4 5 6 7 8 9 10 11 12 13
| @Component public class LoggerInterceptor implements HandlerInterceptor {
@Autowired private User user;
@Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { user.setName("lucy"); return true; } }
|
正常的添加拦截器的配置,有些人(包括自己)由于不太了解,springboot的底层,经常使用new 一个拦截类添加在配置类中,如下所示。
1 2 3 4 5 6 7 8 9
| @Configuration public class InterceptConfiguration implements WebMvcConfigurer {
@Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new LoggerInterceptor()).addPathPatterns("/**"); } }
|
当运行时,由于在拦截器中注入了User类,会报空指针异常,这是因为我们使用的new LoggerInterceptor(),使我们自己创建的对象,并未交给spring管理。
总共有三种方法解决,总的来说是 new的对象不能调用注入的其他类(即有A,B,C三个类,如果在A中new B(),那么在B中就不能@Autowire C,此时的@Autowire注解失效,拦截器的配置类中new 拦截器,而在拦截器中注入另一个对象,会造成@Autowire失效,出现空指针),所以使用@Autowire注解都使用@Autowire注解,使用new都使用创建对象(会有多例的问题),当然还是推荐使用注解,交给Spring管理。
一种方法:在拦截器中也使用new来创建对象(不推荐)
1 2 3 4 5 6 7 8 9 10 11 12
| @Component public class LoggerInterceptor implements HandlerInterceptor {
User user = new User();
@Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { user.setName("lucy"); return true; } }
|
两种注入的方法:
第一种方法:在拦截器的配置类中使用@Bean,如下所示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| @Configuration public class InterceptConfiguration implements WebMvcConfigurer {
@Bean public LoggerInterceptor loggerInterceptor() { return new LoggerInterceptor(); }
@Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(loggerInterceptor).addPathPatterns("/**"); } }
|
第二种方法:在拦截器的配置类使用@Autowire,如下所示。
1 2 3 4 5 6 7 8 9 10 11
| @Configuration public class InterceptConfiguration implements WebMvcConfigurer {
@Autowired private LoggerInterceptor loggerInterceptor;
@Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(loggerInterceptor).addPathPatterns("/**"); } }
|
总结:new的对象不能调用注入的其他类(即有A,B,C三个类,如果在A中new B()
,那么在B中就不能@Autowire C,此时的@Autowire注解失效),所以使用@Autowire注解都使用@Autowire注解,使用new都使用创建对象(会有多例的问题),当然还是推荐使用注解,交给Spring管理。