为什么spring boot拦截器无法注入java bean中
更新时间:2023-12-19第一段
在Spring Boot中,拦截器是一种非常常见的机制,拦截器可以用来验证用户的认证信息、处理跨域请求、记录请求日志等。但是,有时候在拦截器中需要用到一些Java Bean,例如Service实例,但是会发现注入的Java Bean为空。这是因为拦截器是一个普通的Java类,不在Spring的容器中,所以无法自动注入。
public class MyInterceptor implements HandlerInterceptor { @Autowired private MyService myService; ... }
第二段
为了解决这个问题,我们可以使用Spring提供的ApplicationContext来手动注入Java Bean。首先,我们需要在Spring Boot启动类中获取ApplicationContext对象,并在拦截器中使用该对象手动注入Java Bean。具体代码如下:
@SpringBootApplication public class DemoApplication { private static ApplicationContext applicationContext; public static void main(String[] args) { applicationContext = SpringApplication.run(DemoApplication.class, args); } public static ApplicationContext getApplicationContext() { return applicationContext; } }
public class MyInterceptor implements HandlerInterceptor { private MyService myService; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { myService = DemoApplication.getApplicationContext().getBean(MyService.class); ... } ... }
第三段
然而,这种方式会导致在拦截器中手动注入Java Bean的代码过于繁琐和不直观。为了简化手动注入的过程,我们可以继承HandlerInterceptorAdapter类,并在类中添加构造函数。在构造函数中使用@Autowired注解对Java Bean进行自动注入。在使用拦截器时,只需要调用构造函数即可自动注入Java Bean。具体代码如下:
public class MyInterceptor extends HandlerInterceptorAdapter { private MyService myService; @Autowired public MyInterceptor(MyService myService) { this.myService = myService; } ... }
第四段
除了上述两种方法,还可以使用Aware接口。实现ServletContextAware接口,并使用setServletContext方法手动注入ServletContext对象。使用ServletContext对象,可以获取到WebApplicationContext对象,在WebApplicationContext对象中获取Java Bean。具体代码如下:
public class MyInterceptor extends HandlerInterceptorAdapter implements ServletContextAware { private MyService myService; @Override public void setServletContext(ServletContext servletContext) { WebApplicationContext wac = WebApplicationContextUtils.getWebApplicationContext(servletContext); myService = wac.getBean(MyService.class); } ... }