Gerardo Roza
Gerardo Roza

Reputation: 3374

BeanCurrentlyInCreationException after upgrading Boot to 2.6

After upgrading my project to Spring Boot 2.6.0, I'm getting the following exception during startup:

org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'webSecurityConfig': 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-5.3.13.jar:5.3.13]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:227) ~[spring-beans-5.3.13.jar:5.3.13]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.13.jar:5.3.13]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.13.jar:5.3.13]
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:410) ~[spring-beans-5.3.13.jar:5.3.13]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1352) ~[spring-beans-5.3.13.jar:5.3.13]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1195) ~[spring-beans-5.3.13.jar:5.3.13]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582) ~[spring-beans-5.3.13.jar:5.3.13]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) ~[spring-beans-5.3.13.jar:5.3.13]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.13.jar:5.3.13]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.13.jar:5.3.13]

However, my configuration seems to be in line with Spring documentation (HttpSecurity setup, AuthenticationManagerBuilder setup and PasswordEncoder setup):

@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
            .mvcMatchers("/presentations")
            .permitAll()
            .anyRequest()
            .authenticated()
            .and()
            .formLogin();
    }
    
    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
            .withUser("testuser")
            .password(encoder().encode("password"))
            .roles("READ");
    }

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

Upvotes: 11

Views: 15021

Answers (4)

Halilkrkn
Halilkrkn

Reputation: 1

I had taken your problem too. I solved this problem when I added 'spring.main.allow-circular-references=true' into appplication.properties.xml.

Using New Spring WebSecurtyConfig Above Version 2.7.0+

@Configuration
@EnableWebSecurity
@EnableMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig {
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws 
Exception {
        http.authorizeRequests()
                .anyRequest().authenticated()
                .and().httpBasic();
        return http.build();

    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth)
            throws Exception {
        auth.inMemoryAuthentication().withUser("user")
                
.password(passwordEncoder().encode("password")).roles("USER");
    }

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

If you want to use to AuthenticationManagerBuilder auth parameter in configureGlobal function, this method can add 'spring.main.allow-circular-references=true' into appplication.properties.xml.

OR, You can use this method

@Configuration
@EnableWebSecurity
@EnableMethodSecurity(prePostEnabled = true)

public class WebSecurityConfig extends GlobalAuthenticationConfigurerAdapter {

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

    http.authorizeRequests()
           .anyRequest().authenticated()
           .and().httpBasic();
    return http.build();

}

@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
    super.configure(auth);
}
   
}
 

Upvotes: 0

son.nguyen
son.nguyen

Reputation: 1

Change public PasswordEncoder encoder() to static PasswordEncoder encoder()

Upvotes: -1

Ruchira Nawarathna
Ruchira Nawarathna

Reputation: 1477

I got the same error and able to resolve it by using overridden configure method instead of autowired configureGlobal.

Replaced this

@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
    auth.inMemoryAuthentication()
        .withUser("testuser")
        .password(encoder().encode("password"))
        .roles("READ");
}

with this

@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.inMemoryAuthentication()
            .withUser("testuser")
            .password(encoder().encode("password"))
            .roles("READ");
}

Upvotes: 2

Gerardo Roza
Gerardo Roza

Reputation: 3374

Having a closer look at my implementation, it seems the @Autowired method calling the @Bean PasswordEncoder method is generating this issue (this doesn't happen if I call the method from within another @Bean definition method).

The solution was then to move the logic to a different @Configuration class:

@Configuration
public class UsersSetup {
    
    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth, PasswordEncoder encoder) throws Exception {
        auth.inMemoryAuthentication()
        .withUser("testuser")
        .password(encoder.encode("password"))
        .roles("READ");
    }
}

The reason why this appeared with the new Boot version is because Boot now doesn't try to break the dependency cycle automatically by default any more:

https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.6-Release-Notes#circular-references-prohibited-by-default

As an alternative, I could also revert this feature to its former behavior by including the following application property in my project:

spring.main.allow-circular-references=true

Upvotes: 19

Related Questions