【问题标题】:Spring Boot application fails to start due to a circular dependency between 1 bean由于 1 个 bean 之间的循环依赖关系,Spring Boot 应用程序无法启动
【发布时间】:2016-10-03 02:34:10
【问题描述】:

我正在尝试将 JHipster Spring Boot 应用程序从 v1.3.6 版本迁移到最新的 Spring Boot v1.4.1。但是,在这样做之后,我现在在尝试运行应用程序时收到以下错误消息:

***************************
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

我很困惑,因为 UserService 类对 LoadSampleData 类没有任何依赖关系。

错误消息指出只有 1 个 bean 之间存在循环依赖这一事实也令人困惑,因为 bean 如何与自身具有循环依赖关系?

如果有人知道此问题的解决方案,或显示有关循环依赖原因的更具体信息的方法,我们将不胜感激。

如果有帮助,这里是 LoadSampleData 类:

@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() { ... }
}

【问题讨论】:

  • 能不能也加个UserService代码?

标签: java spring-boot


【解决方案1】:

事实证明,UserService 与我项目中名为 EventService 的另一个类存在循环依赖关系。通过从 EventService 中删除 UserService 依赖项,我能够让项目运行。

LoadSampleData 类对 EventService 没有任何依赖关系,因此我不确定为什么错误描述说问题出在 LoadSampleData 类上。

为了找到原因,我必须通过 UserService 并注释掉依赖关系,直到我发现导致问题的那个。

【讨论】:

  • 欢迎来到有趣的Spring开发世界! spring 90% 的“经验”是知道神秘错误信息的含义:D
【解决方案2】:

循环依赖的两种解决方案对我有用:

1) 使用@Lazy 注解

检查控制台上的错误并在所涉及的 bean 上使用 @Lazy 注释。例如:

@Service
public class AuthorizationService {

    @Autowired
    @Lazy
    private EnrollmentService enrollmentService;

但是,这种解决方案并不是最好的,因为它看起来不够优雅,也不一定能防止将来再次发生同样的错误。

2) 重新设计

这是我认为最好的解决方案,因为你真正解决了问题的根源。

就我而言,我注意到堆栈跟踪中的所有“原因”都指向我的 BCryptPasswordEncoder bean,例如:

原因: org.springframework.beans.factory.UnsatisfiedDependencyException: 创建名为“userService”的 bean 时出错:不满足的依赖关系 通过字段“passwordEncoder”表示;嵌套异常是 org.springframework.beans.factory.BeanCurrentlyInCreationException: 创建名为“bCryptPasswordEncoder”的 bean 时出错:请求的 bean 当前正在创建中:是否存在无法解析的循环引用?

然后我意识到我的 BCryptPasswordEncoder 是在我的 SecurityConfig 类中声明的,由于我对依赖项的特殊安排,这导致了循环引用:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

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

所以解决方案是创建另一个配置类来声明 bean:

@Configuration
public class AppConfig {

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

【讨论】:

    猜你喜欢
    • 2020-11-09
    • 2021-12-30
    • 1970-01-01
    • 1970-01-01
    • 2018-09-21
    • 1970-01-01
    • 2015-02-26
    • 1970-01-01
    • 2019-12-19
    相关资源
    最近更新 更多