简体   繁体   中英

Spring Boot application fails to start due to a circular dependency between 1 bean

I am attempting to migrate a JHipster Spring Boot application from version v1.3.6 to the latest Spring Boot v1.4.1. Upon doing so however, I am now receiving the following error message when I try to run the application:

***************************
APPLICATION FAILED TO START
***************************

Description:

There is a circular dependency between 1 beans in the application context:
    - loadSampleData (field private app.service.UserService app.sample.LoadSampleData.userService)
    - userService

I am confused as the UserService class does not have any dependencies on the LoadSampleData class.

The fact that the error message states that there is aa circular dependency between only 1 bean is also confusing, since how does a bean have a circular dependency with itself?

If anyone knows a solution to this problem, or a way to display more specific information about the reason for the circular dependency any help would be appreciated.

Here is the LoadSampleData class if it helps:

@Component
@Profile(Constants.SPRING_PROFILE_DEVELOPMENT)
public class LoadSampleData {

    private static final Logger log = LoggerFactory.getLogger(LoadSampleData.class);

    @Inject
    private UserService userService;

    @PostConstruct
    public void init() { ... }
}

It turned out that the UserService had a circular dependency with another class in my project called EventService. By removing the UserService dependency from EventService I was able to get the project to run.

The LoadSampleData class does not have any dependencies on the EventService so I am not sure why the error description was saying the issue was with the LoadSampleData class.

To find the cause I had to go through the UserService and comment out the dependencies until I discovered the one that was causing the issue.

Two solutions for circular dependency worked for me:

1) Using @Lazy annotation

Check errors on console and use @Lazy annotation on beans involved. For example:

@Service
public class AuthorizationService {

    @Autowired
    @Lazy
    private EnrollmentService enrollmentService;

However, this solution is not the best because it can be seen as not elegant, nor does it necessarily prevent the same error from happening again in the future.

2) Redesign

This is the best solution in my opinion, because you really solve the root of the problem.

In my case, I've noticed that all "caused by" from my stack trace pointed to my BCryptPasswordEncoder bean, for example:

Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'userService': Unsatisfied dependency expressed through field 'passwordEncoder'; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'bCryptPasswordEncoder': Requested bean is currently in creation: Is there an unresolvable circular reference?

Then I realized that my BCryptPasswordEncoder was declared within my SecurityConfig class, which was causing the circular reference due to my particular arrangement of dependencies:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    (...)
    @Bean
    public BCryptPasswordEncoder bCryptPasswordEncoder() {
        return new BCryptPasswordEncoder();
    }

So the solution was creating another configuration class to declare the bean:

@Configuration
public class AppConfig {

    @Bean
    public BCryptPasswordEncoder bCryptPasswordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM