2016-04-21 89 views
0

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

当上下文加载时,Spring在自动连接bean时遇到了困难,因为它们实现了相同的接口。

不幸的是,我使用的是遗留代码,所以我不能直接自动连接这些bean,并使用@Qualifier注释,这就是我试图使用配置类来做到这一点的原因。

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

NoUniqueBeanDefinitionException:无类型的排位豆 [javax.sql.DataSource中]被定义:预期单个匹配豆但 发现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()方法,但有没有更干净的方法来做到这一点?

我对@Primary注释不太熟悉,但是基于我读过的内容,我不知道Spring在这种情况下如何自动调用辅助数据源,因为它看起来总是会选择bean首先是@Primary。

+0

'@ Autowired'注射部位是什么样的?他们都只是'DataSource'字段吗?你100%不能改变他们? – OrangeDog

回答

0

如果您无法更改注入站点以添加限定符,那么您将不得不根据某些逻辑(您未在问题中详述)创建委托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,但可能无法提供您所需的信息。您可能需要通过某种拦截器/方面来获得更高级的信息,以获取基于DataSource选择的调用方的详细信息。

但是它已经实现了,您需要指定一个@Primary bean并将其用作代理。