java - 不能@autowired 存储库。 Bean 循环引用

标签 java spring spring-boot

我的ApiConfig:

@Configuration
@EnableConfigurationProperties(JpaProperties.class)
@EnableJpaRepositories("com.foo.api.persistence")
@ComponentScan("com.foo.api")
@PropertySource("classpath:application.yaml")
public class ApiConfig {

private static final Logger LOGGER = LogManager.getLogger();
private static final String MODEL_PACKAGE = "com.foo.api.model";

@Autowired
private MultiTenantConnectionProviderImpl multiTenantConnectionProvider;

@Autowired
private ApplicationContext applicationContext;

@Resource
private org.springframework.core.env.Environment env;

@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() throws CurrentTenantIdentifierResolverException {
    LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
    entityManagerFactoryBean.setPackagesToScan(MODEL_PACKAGE);
    entityManagerFactoryBean.setPersistenceProviderClass(HibernatePersistenceProvider.class);

    Properties jpaProperties = new Properties();
    jpaProperties.put(Environment.MULTI_TENANT, MultiTenancyStrategy.SCHEMA);
    jpaProperties.put(Environment.MULTI_TENANT_CONNECTION_PROVIDER, multiTenantConnectionProvider);
    jpaProperties.put(Environment.MULTI_TENANT_IDENTIFIER_RESOLVER, getCurrentTenantIdentifierResolver());
    jpaProperties.put(Environment.DIALECT, getHibernateDialect());

    entityManagerFactoryBean.setJpaProperties(jpaProperties);

    return entityManagerFactoryBean;
}

private CurrentTenantIdentifierResolver getCurrentTenantIdentifierResolver() throws CurrentTenantIdentifierResolverException {
    CurrentTenantIdentifierResolver resolver = applicationContext.getBean(CurrentTenantIdentifierResolver.class);
    if (resolver == null) {
        throw new CurrentTenantIdentifierResolverException();
    }

    return resolver;
}

private String getHibernateDialect() {
    return env.getProperty(PropertyConstants.DIALECT);
}

但现在我不能@Autowired我的JpaRepository:

    @Autowired
    private AgreementPersistence agreementPersistence;

协议(protocol)持久化是简单的 repo 从 JpaRepository 扩展而来,具有自己的基于查询的方法;

异常日志:

Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: 

Could not autowire field: AgreementPersistence agreementPersistence; nested exception is org.springframework.beans.factory.BeanCreationException: 

Error creating bean with name 'agreementPersistence': Cannot create inner bean '(inner bean)#38830ea' of type [org.springframework.orm.jpa.SharedEntityManagerCreator] while setting bean property 'entityManager'; nested exception is org.springframework.beans.factory.BeanCreationException: 

Error creating bean with name '(inner bean)#38830ea': Cannot resolve reference to bean 'entityManagerFactory' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: 

Error creating bean with name 'entityManagerFactory': Requested bean is currently in creation: Is there an unresolvable circular reference?

如何解决? 也许我可以设置一些 bean 创建顺序或其他东西?

还有: 我需要在另一个模块的配置类中使用@Autowired repo。

最佳答案

循环引用是指您有两个 bean,每个 bean 都注入(inject)到另一个。

@Service
public class A {
    @Inject
    private B b;
}

@Service
public class B {
    @Inject
    private A a;
}

由于 Spring 无法注入(inject)未完全实例化的东西,因此它无法在 B 注入(inject)之前将 A 注入(inject)到 BA,反之亦然,从而使 Spring 卡住。

在这些情况下你应该首先分析,看看是否真的需要循环依赖。也许将 bean 分解成这样的东西才是您真正需要的:

@Service
public class C {
    @Inject
    private A a;
    @Inject
    private B b;
}

如果您无法分解解决问题的方法,这是解决问题的一种方法:

@Service
public class A {
    @Inject
    private B b;
}

@Service
public class B extends ApplicationContextAware {
    //no inject
    private A a;

    private ApplicationContext applicationContext;

    public void setApplicationContext(final ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    @PostConstruct
    public void handleDependencies() {
        this.a = applicationContext.getBean(A.class);
    }
}

关于java - 不能@autowired 存储库。 Bean 循环引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36913014/

相关文章:

java - Java Servlet 中静态变量的使用(例如在 AppEngine 中)

java - org.apache.catalina.LifecycleException java spring boot

java - 在单元测试中捕获 SQLException 而不是 Spring DataIntegrityViolationException

java - 找不到 Spring Boot 资源

spring - logback 日志总是将 show_sql 设置为 false 的 hibernate 查询

java - 类文件 javax/validation/ConstraintViolationException 中非 native 或抽象方法中缺少代码属性

Java 性能运行时泛型

java - Selenium 是否等待 JavaScript 完成?

java - Hibernate Envers - DefaultRevisionEntity 无法转换为 javassist.util.proxy.Proxy

java - 映射 @Entity 时出现 UnsatisfiedDependencyException beancreationerror