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

Spring Security Bean循环依赖错误求助:BeanCurrentlyInCreationException排查

Spring Boot Security 循环依赖问题排查与解决

问题描述

启动Spring Boot应用时触发循环依赖错误,核心日志如下:

Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
2024-07-18T18:36:31.217+05:30 ERROR 16888 --- [           main] o.s.boot.SpringApplication               : Application run failed

org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'springSecurity': Requested bean is currently in creation: Is there an unresolvable circular reference?  
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.beforeSingletonCreation(DefaultSingletonBeanRegistry.java:355) ~[spring-beans-6.1.8.jar:6.1.8]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:227) ~[spring-beans-6.1.8.jar:6.1.8]

相关代码

Spring Security配置类

@Configuration 
@EnableWebSecurity 
public class SpringSecurity {
@Autowired
private UserDetailsServiceImpl userDetailsService;

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {

    return http.authorizeHttpRequests(request -> request
                    .requestMatchers("/public/**").permitAll()
                    .requestMatchers("/journal/**", "/user/**").authenticated()
                    .requestMatchers("/admin/**").hasRole("ADMIN")
                    .anyRequest().authenticated())
            .httpBasic(Customizer.withDefaults())
            .csrf(AbstractHttpConfigurer::disable)
            .build();
}

@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
    auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}

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

POM.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.2.6</version>
        <relativePath/>
    </parent>
    <groupId>net.engineeringdigest</groupId>
    <artifactId>journalApp</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>JournalApp</name>
    <description>Application for Journals</description>
    <properties>
        <java.version>17</java.version>
    </properties>
    <dependencies>

<dependency>
        <version>3.1.4</version>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-mongodb</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.30</version>
        <scope>provided</scope>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>

</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

问题原因与解决方法

核心原因

  1. 配置类命名为SpringSecurity,Spring默认将其bean名称设为springSecurity,与框架内部组件名称冲突,初始化时触发循环引用。
  2. configureGlobal(AuthenticationManagerBuilder)是Spring Security 5.x及更早版本的过时写法,在6.x版本中直接调用passwordEncoder()会绕开Spring容器管理,导致依赖初始化顺序混乱。

修复方案

修改配置类,采用Spring Security 6.x推荐的配置方式,同时规避命名冲突:

修改后的配置类

@Configuration 
@EnableWebSecurity 
public class SpringSecurityConfig {
    private final UserDetailsServiceImpl userDetailsService;
    private final PasswordEncoder passwordEncoder;

    // 构造函数注入,符合Spring最佳实践,避免循环依赖
    public SpringSecurityConfig(UserDetailsServiceImpl userDetailsService, PasswordEncoder passwordEncoder) {
        this.userDetailsService = userDetailsService;
        this.passwordEncoder = passwordEncoder;
    }

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        return http.authorizeHttpRequests(request -> request
                        .requestMatchers("/public/**").permitAll()
                        .requestMatchers("/journal/**", "/user/**").authenticated()
                        .requestMatchers("/admin/**").hasRole("ADMIN")
                        .anyRequest().authenticated())
                .httpBasic(Customizer.withDefaults())
                .csrf(AbstractHttpConfigurer::disable)
                // 直接绑定认证相关Bean
                .userDetailsService(userDetailsService)
                .passwordEncoder(passwordEncoder)
                .build();
    }

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

关键修改点

  • 重命名配置类为SpringSecurityConfig,避免与框架内部bean名称冲突。
  • 使用构造函数注入替代字段注入,明确依赖初始化顺序,消除循环依赖风险。
  • 移除过时的configureGlobal方法,直接在SecurityFilterChain中绑定UserDetailsService和PasswordEncoder。
  • 确保UserDetailsServiceImpl类添加@Service注解,让Spring能自动扫描并创建其bean实例。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 20:42:16