问题: 在 Spring Security 的过滤器链中,使用 @Autowired 注入 UserService 时出现 null。
代码示例:
@Autowired
private UserService userService;
原因:
-
创建时机问题:Filter 实例可能在 Spring 完全初始化 ApplicationContext 之前被创建和初始化。这可能导致某些 beans 尚未完全准备好,使得 @Autowired 不起作用。
-
非 Spring 管理的对象:如果通过
new WeChatAuthenticationFilter()手动创建过滤器实例,则该实例不受 Spring 管理,导致依赖无法注入。 -
上下文问题:在具有多个 Spring 上下文的项目中,如果过滤器不在主上下文中,@Autowired 可能不会正确工作。
推荐解决方法:构造器注入
构造器注入是 Spring 团队推荐的依赖注入方式。这种方法可以确保对象在构造时具有其所有必需的依赖。
在此例中,我们使用构造器注入将 WeChatAuthenticationFilter 注入到 SecurityConfig 类中。这种方法确保了在创建 SecurityConfig bean 时,WeChatAuthenticationFilter 已被注入,而不会是 null。
@Autowired
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private final WeChatAuthenticationFilter weChatAuthenticationFilter;
@Autowired
public SecurityConfig(WeChatAuthenticationFilter weChatAuthenticationFilter) {
this.weChatAuthenticationFilter = weChatAuthenticationFilter;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable() // 可能需要禁用 CSRF,取决于你的需求
.authorizeRequests()
.antMatchers("/user/login/**").permitAll() // 公开的路由不需要身份验证
.anyRequest().authenticated() // 其他的路由都需要身份验证
.and()
.httpBasic().disable() // 禁用 HTTP Basic 认证
.formLogin().disable() // 禁用表单登录
.addFilterBefore(weChatAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
}
}
WeChatAuthenticationFilter代码示例:
@Component
public class WeChatAuthenticationFilter extends OncePerRequestFilter {
private final UserService userService;
private final JwtUtil jwtUtil;
@Autowired
public WeChatAuthenticationFilter(UserService userService, JwtUtil jwtUtil) {
this.userService = userService;
this.jwtUtil = jwtUtil;
}
// ... 其余的代码 ...
}
优点:
-
明确的依赖关系:你明确地告诉 Spring
WeChatAuthenticationFilter需要哪些依赖。当创建这个 bean 时,Spring 会确保注入这些依赖。 -
始终处于有效状态:使用构造器,可以确保对象在构造时具有所有必需的依赖。
-
避免字段注入的副作用:字段注入可能导致对象在某些时候处于无效状态。使用构造器注入可以避免这种情况。
总结:当在 Spring Security 或其他过滤器中工作时,使用构造器注入是更可靠的方式,因为它确保了所有必要的依赖在对象创建时都已正确注入。
文章讨论了SpringSecurity中@Autowired注入失败的问题,分析了创建时机和上下文问题,推荐使用构造器注入来确保依赖在对象创建时就已正确注入,以提高可靠性。

被折叠的 条评论
为什么被折叠?



