应用上下文中一些bean的依赖形成了一个循环

Posted

技术标签:

【中文标题】应用上下文中一些bean的依赖形成了一个循环【英文标题】:The dependencies of some of the beans in the application context form a cycle 【发布时间】:2017-05-27 07:06:43 【问题描述】:

我正在使用 JPA 开发 Spring Boot v1.4.2.RELEASE 应用程序。

我定义了存储库接口和实现

ARepository

@Repository
public interface ARepository extends CrudRepository<A, String>, ARepositoryCustom, JpaSpecificationExecutor<A> 

ARepositoryCustom

@Repository
public interface ARepositoryCustom 
    Page<A> findA(findAForm form, Pageable pageable);

ARepositoryImpl

@Repository
public class ARepositoryImpl implements ARepositoryCustom 
    @Autowired
    private ARepository aRepository;
    @Override
    public Page<A> findA(findAForm form, Pageable pageable) 
        return aRepository.findAll(
                where(ASpecs.codeLike(form.getCode()))
                .and(ASpecs.labelLike(form.getLabel()))
                .and(ASpecs.isActive()),
                pageable);
    

还有服务 AServiceImpl

@Service
public class AServiceImpl implements AService 
    private ARepository aRepository;
    public AServiceImpl(ARepository aRepository) 
        super();
        this.aRepository = aRepository;
    
    ...

我的应用程序不会以消息开头:

****************************** 应用程序无法启动 ****************************** 描述: : |一个RepositoryImpl └──────┘

我遵循http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.single-repository-behaviour中描述的所有步骤

请帮忙!

劳伦特

【问题讨论】:

尝试从ARepositoryCustom中删除注释@Repository 不需要将ARepositoryCustom 标记为@Repository,因为您想提供它的实现而不是使用Spring Data 生成它 你有一个接口ARepository,它扩展了ARepositoryCustom,接下来在你使用接口ARepository的实现中。我怀疑 SPring Data Jpa 能否解决问题。恕我直言,该方法属于您的服务而不是您的存储库。 【参考方案1】:

使用@Lazy注解即可解决

@Component
public class Bean1 
    @Lazy
    @Autowired
    private Bean2 bean2;

【讨论】:

【参考方案2】:

使用@Lazy

打破循环的一种简单方法是说 Spring 懒惰地初始化其中一个 bean。也就是说:它不会完全初始化 bean,而是创建一个代理将其注入另一个 bean。注入的 bean 只有在第一次需要时才会完全创建。

@Service
public class AServiceImpl implements AService 
    private final ARepository aRepository;
    public AServiceImpl(@Lazy ARepository aRepository) 
        super();
        this.aRepository = aRepository;
    
    ...

来源:https://www.baeldung.com/circular-dependencies-in-spring

【讨论】:

其实@lazy帮了我 感谢添加源代码,因为它有助于以不同于 @lazy 的方式解决问题【参考方案3】:

有一个简单的解决方法可以解决您原来的问题: 只需从 ARepositoryCustom 和 ARepositoryImpl 中删除 @Repository。 保留所有命名和接口/类层次结构。他们都没事。

【讨论】:

【参考方案4】:

我测试了你的源代码,发现了一些棘手的问题。

首先,使用您的源代码,我收到以下错误:

There is a circular dependency between 1 beans in the application context:
- ARepositoryImpl (field private test.ARepository test.ARepositoryImpl.aRepository)
- aRepositoryImpl

然后,我猜 Spring 在 ARepository(JPA 存储库)和 ARepositoryImpl(自定义存储库)之间“混淆”了。 因此,我建议您将ARepository重命名为其他名称,例如BRepository。如果我重命名类名,它会起作用。

根据 Spring Data (https://docs.spring.io/spring-data/jpa/docs/current/reference/html/) 的官方文档:

这些类需要遵循将命名空间元素的属性repository-impl-postfix附加到找到的存储库接口名称的命名约定。 此后缀默认为 Impl

【讨论】:

以上是关于应用上下文中一些bean的依赖形成了一个循环的主要内容,如果未能解决你的问题,请参考以下文章

升级后的 Spring Boot Oauth2 自动配置周期

不同项目中的应用程序上下文空且无法访问bean

深谈Spring如何解决Bean的循环依赖

Spring之Bean的自动装配

使用 CDI(上下文和依赖注入)支持 bean 而不是托管 Bean

装配Bean