You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot 3.3.4循环依赖问题求助:UnsatisfiedDependencyException报错

解决Spring Boot 3.3.4中WebSecurityConfig的循环依赖问题

报错原因

你遇到的UnsatisfiedDependencyException是因为WebSecurityConfig通过构造器注入了PasswordEncoder,而PasswordEncoder的@Bean方法又定义在同一个类中。Spring容器在创建WebSecurityConfig实例时,需要先获取PasswordEncoder Bean,但PasswordEncoder的Bean创建依赖WebSecurityConfig类的实例(Bean方法属于该类),从而形成无法解析的循环依赖。

解决方案

方案1:移除构造器注入,直接调用本地@Bean方法

由于passwordEncoder()是被@Bean标记的方法,Spring会保证每次调用都返回容器中的单例Bean实例,因此可以直接在需要的地方调用该方法,无需注入:

package elements.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

@Configuration
@EnableWebSecurity
public class WebSecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .anyRequest().authenticated()
                .and()
            .formLogin()
                .loginPage("/login")
                .permitAll()
                .and()
            .logout()
                .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
                .logoutSuccessUrl("/login");
        return http.build();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return NoOpPasswordEncoder.getInstance();
    }

    // 移除@Autowired,直接调用passwordEncoder()方法
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth
            .inMemoryAuthentication()
                .withUser("user1ka").password(passwordEncoder().encode("y445uri125")).roles("USER")
            .and()
                .withUser("user2ka").password(passwordEncoder().encode("sa678sha769")).roles("USER");
    }
}

方案2:使用@Lazy延迟加载PasswordEncoder

如果需要保留构造器注入,可以通过@Lazy注解延迟PasswordEncoder的初始化,打破循环依赖链:

// 修改构造器注入部分
@Autowired
public WebSecurityConfig(@Lazy PasswordEncoder passwordEncoder) {
    this.passwordEncoder = passwordEncoder;
}

额外建议

NoOpPasswordEncoder已被标记为过时,生产环境中强烈建议使用安全的密码编码器,比如BCryptPasswordEncoder:

@Bean
public PasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder();
}

内容的提问来源于stack exchange,提问作者Ganiel24

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 12:25:19