SpringBoot拦截器中Bean无法注入

因为拦截器在 Bean 初始化之前进行,所以在拦截器中无法像这样注入 Bean

  1. @Autowired
  2. private UserRepository userRepository;

 

方法一、

为了解决这个问题,我们在拦截器方法里,创建一个 BeanFactory 的实例,然后调用其 getBean() 方法来获取我们需要的 Bean 实例。

比如我们这里需要获取 userRepoditory 对象,可以这样(37-38行)

  1. public class SessionInterceptor implements HandlerInterceptor {
  2.     @Autowired
  3.     private UserRepository userRepository;
  4.     /**
  5.      * 在请求处理之前进行调用(Controller方法调用之前)
  6.      */
  7.     @Override
  8.     public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
  9.         return true;
  10.     }
  11.     /**
  12.      * 在请求处理之后调用,但是在视图被渲染之前(Controller方法调用之后)
  13.      *
  14.      * @param request
  15.      * @param response
  16.      * @param handler
  17.      * @param modelAndView
  18.      * @throws Exception
  19.      */
  20.     @Override
  21.     public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
  22.         System.out.println("拦截了");
  23.         if(request.getSession().getAttribute("user") == null) {
  24.             //如果用户授权存在,添加Session
  25.             try {
  26.                 SecurityContext securityContext = SecurityContextHolder.getContext();
  27.                 Authentication authentication = securityContext.getAuthentication();
  28.                 Object principal = authentication.getPrincipal();
  29.                 if (principal != null && principal instanceof UserDetails) {
  30.                     String username = ((UserDetails) principal).getUsername();
  31.                     if(userRepository == null) {
  32.                         BeanFactory factory = WebApplicationContextUtils.getRequiredWebApplicationContext(request.getServletContext());
  33.                         userRepository = (UserRepository) factory.getBean("userRepository");
  34.                         User user = userRepository.findByUsername(username);
  35.                         request.getSession().setAttribute("user", user);
  36.                     }
  37.                 }
  38.             } catch (Exception e) {
  39.                 e.printStackTrace();
  40.             }
  41.         }
  42.     }
  43.     /**
  44.      * 在整个请求调用之后被调用,也就是在 DispatcherServlet 渲染了对应的视图后执行(主要用于资源清理)
  45.      *
  46.      * @param request
  47.      * @param response
  48.      * @param handler
  49.      * @param ex
  50.      * @throws Exception
  51.      */
  52.     @Override
  53.     public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
  54.     }
  55. }

 

方法二、推荐

WebMvcConfig.java  监听器

  1. @Configuration
  2. public class WebMvcConfig implements WebMvcConfigurer {
  3.     @Bean
  4.     SessionInterceptor sessionInterceptor() {
  5.         return new SessionInterceptor();
  6.     }
  7.     @Override
  8.     public void addInterceptors(InterceptorRegistry registry) {
  9.         //拦截器按照顺序执行
  10.         registry.addInterceptor(sessionInterceptor())
  11.                 .addPathPatterns("/**")
  12.                 .excludePathPatterns("/components/**","/css/**","/js/**","/img/**","/logout");
  13.     }
  14. }

 

SessionInterceptor 拦截器

  1. public class SessionInterceptor implements HandlerInterceptor {
  2.     @Autowired
  3.     private UserRepository userRepository;
  4.     @Autowired
  5.     private UserService userService;
  6.     /**
  7.      * 在请求处理之前进行调用(Controller方法调用之前)
  8.      */
  9.     @Override
  10.     public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
  11.         return true;
  12.     }
  13.     /**
  14.      * 在请求处理之后调用,但是在视图被渲染之前(Controller方法调用之后)
  15.      *
  16.      * @param request
  17.      * @param response
  18.      * @param handler
  19.      * @param modelAndView
  20.      * @throws Exception
  21.      */
  22.     @Override
  23.     public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
  24.         UserVO userSession = (UserVO) request.getSession().getAttribute("user");
  25.         if (userSession == null) {
  26.             //如果用户授权存在,添加Session
  27.             if (SecurityContextHolder.getContext().getAuthentication() != null && SecurityContextHolder.getContext().getAuthentication().isAuthenticated()
  28.                     && !SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString().equals("anonymousUser")) {
  29.                 User principal = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
  30.                 User user = userRepository.findByUsername(principal.getUsername());
  31.                 UserVO userVO = userService.getUserVO(user);
  32.                 request.getSession().setAttribute("user", userVO);
  33.             }
  34.         }
  35.     }
  36.     /**
  37.      * 在整个请求调用之后被调用,也就是在 DispatcherServlet 渲染了对应的视图后执行(主要用于资源清理)
  38.      *
  39.      * @param request
  40.      * @param response
  41.      * @param handler
  42.      * @param ex
  43.      * @throws Exception
  44.      */
  45.     @Override
  46.     public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
  47.     }
  48. }

 

参考:

https://stackoverflow.com/questions/23349180/java-config-for-spring-interceptor-where-interceptor-is-using-autowired-spring-b

https://my.oschina.net/gmd/blog/699385

  • 微信
  • 赶快加我聊天吧
  • weinxin
  • 博客/Java交流群
  • 资源分享,问题解决,技术交流。群号:590480292
  • weinxin
广告也精彩
言曌
广告也精彩

发表评论

:?::razz::sad::evil::!::smile::oops::grin::eek::shock::???::cool::lol::mad::twisted::roll::wink::idea::arrow::neutral::cry::mrgreen: