繁体   English   中英

如何使用Spring @Configuration类配置多个JPA数据源?

[英]How do I configure multiple JPA data sources using Spring @Configuration class?

我正在尝试使用Spring的@Configuration类在同一应用程序上下文中配置多个JPA实体/事务管理器。

当上下文加载时,Spring很难自动装配Bean,因为它们实现了相同的接口。

不幸的是,我使用的是旧版代码,所以我无法直接自动连接Bean并使用@Qualifier批注,这就是为什么我尝试使用配置类来做到这一点。

@Bean声明中,是否有任何方法可以限定应该注入哪个bean? 我认为使用直接方法调用就足够了,但是通常会导致诸如

NoUniqueBeanDefinitionException:没有定义类型为[javax.sql.DataSource]的合格bean:期望的单个匹配bean,但找到了4

这是我要在下面执行的操作的示例:

@Configuration    
public class ApplicationConfig {

@Bean(name = "transactionManager1")
public PlatformTransactionManager transactionManager1() {
    return new JpaTransactionManager(entityManagerFactory1());
}

@Bean(name = "entityManagerFactory1")
public EntityManagerFactory entityManagerFactory1() {
    ...
    LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
    factory.setDataSource(dataSource1());
    ...
}

@Bean(destroyMethod = "")
@ConfigurationProperties(prefix = "datasource.test1")
public JndiObjectFactoryBean jndiObjectFactoryBean1() {
    return new JndiObjectFactoryBean();
}

@Bean(name = "dataSource1")
public DataSource dataSource1() {
    JndiDataSourceLookup lookup = new JndiDataSourceLookup();
    return lookup.getDataSource(jndiObjectFactoryBean1().getJndiName());
}

@Bean(name = "transactionManager2")
public PlatformTransactionManager transactionManager2() {
    return new JpaTransactionManager(entityManagerFactory2());
}

@Bean(name = "entityManagerFactory2")
public EntityManagerFactory entityManagerFactory2() {
    ...
    LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
    factory.setDataSource(dataSource2());
    ...
}

@Bean(destroyMethod = "")
@ConfigurationProperties(prefix = "datasource.test2")
public JndiObjectFactoryBean jndiObjectFactoryBean2() {
    return new JndiObjectFactoryBean();
}

@Bean(name = "dataSource2")
public DataSource dataSource2() {
    JndiDataSourceLookup lookup = new JndiDataSourceLookup();
    return lookup.getDataSource(jndiObjectFactoryBean2().getJndiName());
}

我想我可以尝试直接通过Spring上下文的getBean()方法注入bean,但是有没有更干净的方法?

我不太熟悉@Primary批注,但是根据我所读的内容,我不知道在这种情况下spring如何自动连接辅助数据源,因为看起来它总是会首先使用@Primary来选择bean。 。

如果您不能更改注入站点以添加限定符,那么您将必须基于某种逻辑(在问题中没有详细介绍)创建一个委派的DataSource

这样的事情。

@Primary @Bean
public DelegatingDataSource delegatingDataSource(List<DataSource> sources) {
    return new DelegatingDataSource() {
        @Override
        public DataSource getTargetDataSource() {
            // decide which dataSource to delegate to
            return sources.get(0);
        }
    }
}

我使用了DelegatingDataSource ,但可能无法提供您所需要的。 您可能需要使用某种拦截器/方面进行更高级的设计,以获取作为数据源选择基础的调用方的详细信息。

无论实现它如何,您都需要指定一个@Primary bean并将其用作代理。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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