运行Spring Security配置类出现PasswordEncoder循环引用错误的排查与解决
错误原因
这是典型的循环依赖问题:
- 初始化
AuthenticationManagerBuilder时,直接调用passwordEncoder()方法获取Bean,此时PasswordEncoder实例还在Spring的创建流程中。 - 同时定义的
AuthenticationManagerBean依赖AuthenticationConfiguration,而AuthenticationConfiguration内部又会依赖配置好的AuthenticationManagerBuilder,形成闭环依赖链,导致Spring无法完成Bean初始化,最终抛出循环依赖错误。 - 直接调用
passwordEncoder()的行为绕开了Spring的Bean代理机制,进一步加剧了依赖冲突的概率。
解决方法
推荐两种实用的解决方式:
方式一:注入PasswordEncoder到配置方法
把PasswordEncoder作为参数注入到configureGlobal方法,让Spring处理依赖注入,避免直接调用方法:
@Autowired public void configureGlobal(AuthenticationManagerBuilder authenticationManagerBuilder, PasswordEncoder passwordEncoder) throws Exception { authenticationManagerBuilder.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder); }
方式二:使用Lambda风格配置(Spring Security 5.7+推荐)
直接在SecurityFilterChain中配置userDetailsService和passwordEncoder,删除冗余的configureGlobal方法,这种方式符合新版本Spring Security设计规范,能彻底避免循环依赖:
@Bean public SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception { return httpSecurity .csrf(csrf -> csrf.disable()) .authorizeHttpRequests(auth -> auth .requestMatchers("/api/auth/**").permitAll() .anyRequest().authenticated() ) // 直接配置用户详情服务和密码编码器 .userDetailsService(userDetailsService) .passwordEncoder(passwordEncoder()) .build(); }
额外提示:如果业务不需要自定义AuthenticationManager,可以直接删除authenticationManager这个Bean,Spring Security会自动配置默认实例,进一步简化代码。
内容的提问来源于stack exchange,提问作者Ulaganaathan
相关产品推荐
相关产品推荐

