我的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)到 B
中A
,反之亦然,从而使 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/