2015-06-22 88 views
1

我有一個類EntityLoader,它用於使用Hibernate從MySQL數據庫中提取一些數據。但是現在需要從兩個不同的數據庫(在這種情況下是MySQL和Oracle)中獲取數據。所以我想要兩個豆EntityLoader,但在每一個注入不同的SessionFactory使用XML配置覆蓋@Autowired屬性註釋

EntityLoader定義如下:

package com.demo 

@Component 
public class EntityLoader { 

    @Autowired 
    private SessionFactory sessionFactory; 

    /* Code ... */ 

    public SessionFactory getSessionFactory() { 
     return sessionFactory; 
    } 

    public void setSessionFactory(SessionFactory sessionFactory) { 
     this.sessionFactory = sessionFactory; 
    } 
} 

和上下文的配置是:

<context:component-scan base-package="com.demo" /> 
<bean id="mysqlSessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> 

到目前爲止,它工作正常。在此我也做了以下變化:

  • ,以避免自動創建一個EntityLoader的
  • 添加mysqlSessionFactoryoracleSessionFactory bean定義
  • 添加mysqlEntityRepoLoaderoracleEntityRepoLoader bean定義排除EntityLoadercomponent-scan

請注意,在mysqlEntityRepoLoaderoracleEntityRepoLoader中,我添加了屬性autowired="no"希望這會讓 告訴Spring不要自動調用SessionFactory,而是使用定義的ref。

生成的配置是:

<context:component-scan base-package="com.demo"> 
    <context:exclude-filter type="regex" expression="com.demo.EntityLoader"/> 
</context:component-scan> 

<bean id="mysqlSessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> 
    <!-- ... config ... --> 
</bean> 
<bean id="oracleSessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> 
    <!-- ... config ... --> 
</bean> 

<bean id="mysqlEntityRepoLoader" class="com.dome.imserso.api.core.data.EntityRepoLoader" autowire="no"> 
    <property name="sessionFactory" ref="mysqlSessionFactory"/> 
</bean> 
<bean id="oracleEntityRepoLoader" class="com.dome.imserso.api.core.data.EntityRepoLoader" autowire="no"> 
    <property name="sessionFactory" ref="oracleSessionFactory"/> 
</bean> 

但似乎春天首先嚐試自動裝配的SessionFactory在任何情況下。我得到以下錯誤:

No qualifying bean of type [org.hibernate.SessionFactory] is defined: expected single matching bean but found 2: mysqlSessionFactory,oracleSessionFactory

如果我刪除@Autowired一切工作正常。但我想維護它,因爲此代碼是用於其他應用程序的通用庫的一部分,通常情況下僅從一個數據庫加載。

有沒有辦法在不移除註釋的情況下完成它?

+0

您可以創建一個名爲'sessionFactory'的虛擬bean ... – araknoid

+0

只需從「EntityLoader」中刪除「@ Component」註釋?您手動創建XML實例(因此不需要「@ Component」),並且您正在通過調用'setSessionFactory'方法(所以不需要'@ Autowired')在會話工廠中手動接線。 –

+0

如果我刪除了註釋,那麼我需要在使用它的所有其他應用程序中以XML配置此Bean。我的意圖正是爲了避免這一點。 –

回答

3

如果你可以修改你的LIB包含EntityLoader,以下2步將做行程:

  1. EntityLoader讓你@Autowired可選:

    @Autowired(所需= FALSE)

  2. 在XML配置,排除自動裝配候選人mysqlSessionFactory和oracleSessionFactory豆,加autowire-candidate="false"每個SessionFactory的:

<bean id="mysqlSessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" autowire-candidate="false"> 
    <!-- ... config ... --> 
</bean> 
<bean id="oracleSessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" autowire-candidate="false"> 
    <!-- ... config ... --> 
</bean> 

瞧!

+0

謝謝!你是對的!關鍵是'autowire-candidate =「false」' –

0

這是導致問題的組件掃描。您的豆已經手動創建,但Spring正在嘗試創建另一個EntityLoader,因爲組件掃描正在拾取您的@Component註釋。

你可以告訴組件掃描(只是你的應用程序)忽略類:

<context:component-scan ...> 
    <context:exclude-filter expression="com\.demo\.EntityLoader" type="regex" /> 
</context:component-scan> 
+0

我已經在'component-scan'中使用'exclude-filter'。無論如何,如果我刪除'@ Component'但保留'@ Autowired',問題依然存在。 –

+0

我認爲問題是spring autowires屬性忽略了我的xml配置。就好像註釋優先於xml一樣。 –