SpringBoot--Spring MVC 拦截器注入与 new 的区别
1️⃣ 核心概念
Spring MVC 的拦截器(
HandlerInterceptor)可以用两种方式注册:
由 Spring 管理的 Bean 注入
通过
@Component或@Bean注入拦截器内部可以使用
@Autowired注入其他 Bean直接 new 一个对象
拦截器内部不依赖 Spring Bean,完全自给自足
不会触发 Spring 的依赖注入和生命周期管理
什么时候用哪个?
3.1.拦截器需要依赖注入的情况
如果拦截器中需要通过
@Autowired注入属性,例如:@Component public class TokenIntercept implements HandlerInterceptor { @Autowired private RedisTemplate redisTemplate; }
则拦截器类必须加上
@Component,由 Spring 容器管理。在
WebMvcConfigurer中必须通过@Autowired注入该拦截器:@Autowired private TokenIntercept tokenIntercept;
如果使用
new TokenIntercept()直接创建实例,拦截器内部的redisTemplate将会是null,依赖注入无法生效。3.2.拦截器不依赖注入的情况
如果拦截器内部不需要通过
@Autowired注入属性,则类上加不加@Component都可以。
在
WebMvcConfigurer中可以通过@Autowired注入,也可以直接new实例:registry.addInterceptor(new LoginInterceptor());
因为拦截器内部没有依赖注入的属性,所以无论 Spring 管理与否,都不会影响拦截器的功能。
2️⃣ 为什么要注意这个区别?
情况 方法 原因 拦截器内部需要注入其他 Bean(Redis、JWT、Service 等) 通过 Spring 注入 ( @Component+@Autowired)直接 new拦截器不会触发依赖注入,内部对象为 null拦截器内部不需要依赖 Bean 可以直接 new简单轻量,不依赖 Spring 管理 💡 关键点:是否依赖 Spring 注入决定能否直接 new。
3️⃣ 例子对比
3.1 通过 Spring 注入
@Component public class TokenIntercept implements HandlerInterceptor { @Autowired private RedisUtil redisUtil; @Autowired private JwtUtil jwtUtil; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { System.out.println("拦截器拦截请求"); String token = request.getHeader("token"); if (token == null) return false; String userId = jwtUtil.parseJWT(token); String redisToken = (String) redisUtil.get("token:userId:" + userId); return token.equals(redisToken); } } @Configuration public class TokenInterceptConfig implements WebMvcConfigurer { @Autowired private TokenIntercept tokenIntercept; // 注入 Spring 管理的 Bean @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(tokenIntercept) .excludePathPatterns("/login/**","/register/**") .addPathPatterns("/**"); } }✅ 特点:
TokenIntercept内部依赖RedisUtil和JwtUtil必须通过
@Autowired注入,不能new
3.2 直接 new 对象
public class LoginInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { System.out.println("登录拦截器拦截请求"); return true; } } @Configuration public class MvcConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new LoginInterceptor()) // 直接 new .excludePathPatterns("/login/**", "/register/**"); } }✅ 特点:
拦截器内部没有依赖 Spring Bean
直接
new就可以使用生命周期由程序管理,Spring 不会干预
4️⃣ 总结
是否依赖注入 决定拦截器是否可以直接 new:
依赖注入 → 必须通过 Spring 容器管理
不依赖 → 可直接 new
注意事项:
如果直接 new,会导致拦截器内部的
@Autowired失效Spring 管理的 Bean 可以享受 AOP、事务、依赖注入等功能
最佳实践:
推荐:所有需要依赖注入的拦截器都使用 Spring 容器管理
简单拦截器(如日志、统计、权限判断)可以直接 new
更多推荐


所有评论(0)