在 Spring Security 的过滤器链中,使用 `@Autowired` 注入 `UserService` 时出现 `null`

文章讨论了SpringSecurity中@Autowired注入失败的问题,分析了创建时机和上下文问题,推荐使用构造器注入来确保依赖在对象创建时就已正确注入,以提高可靠性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题: 在 Spring Security 的过滤器链中,使用 @Autowired 注入 UserService 时出现 null

代码示例:

@Autowired
private UserService userService;

原因:

  1. 创建时机问题:Filter 实例可能在 Spring 完全初始化 ApplicationContext 之前被创建和初始化。这可能导致某些 beans 尚未完全准备好,使得 @Autowired 不起作用。

  2. 非 Spring 管理的对象:如果通过 new WeChatAuthenticationFilter() 手动创建过滤器实例,则该实例不受 Spring 管理,导致依赖无法注入。

  3. 上下文问题:在具有多个 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;
    }
    // ... 其余的代码 ...
}

优点:

  1. 明确的依赖关系:你明确地告诉 Spring WeChatAuthenticationFilter 需要哪些依赖。当创建这个 bean 时,Spring 会确保注入这些依赖。

  2. 始终处于有效状态:使用构造器,可以确保对象在构造时具有所有必需的依赖。

  3. 避免字段注入的副作用:字段注入可能导致对象在某些时候处于无效状态。使用构造器注入可以避免这种情况。


总结:当在 Spring Security 或其他过滤器中工作时,使用构造器注入是更可靠的方式,因为它确保了所有必要的依赖在对象创建时都已正确注入。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值