c语言编程笔录

首页 >   > 笔记大全

笔记大全

为什么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);
    }
    ...
}