使用XML配置覆盖@Autowired属性注释

时间:2015-06-22 12:31:19

标签: java spring spring-annotations xml-configuration

我曾经使用Hibernate从MySQL数据库中获取一些数据EntityLoader。但现在需要从两个不同的数据库(在这种情况下是MySQL和Oracle)中获取数据。所以我希望有两个EntityLoader的bean,但每个bean都注入了不同的SessionFactory

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排除component-scan以避免自动创建EntityLoader
  • 添加mysqlSessionFactoryoracleSessionFactory bean定义
  • 添加mysqlEntityRepoLoaderoracleEntityRepoLoader bean定义

请注意,在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> 

但似乎Spring在任何情况下首先尝试自动装配SessionFactory。我收到以下错误:

  

没有定义类型为[org.hibernate.SessionFactory]的限定bean:   预期单匹配bean但发现2:   mysqlSessionFactory,oracleSessionFactory

如果我删除@Autowired一切正常。但我想维护它,因为这段代码是用于其他应用程序的通用库的一部分,其中通常的情况是只从一个数据库加载。

有没有办法在不删除注释的情况下完成它?

2 个答案:

答案 0 :(得分:3)

如果您能够修改包含EntityLoader的lib,请执行以下两步操作:

  1. EntityLoader中设置@Autowired可选:

    @Autowired(所需=假)

  2. 在XML配置中,从autowire候选者中排除mysqlSessionFactory和oracleSessionFactory bean,将autowire-candidate="false"添加到每个sessionFactory:

  3. <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>
    

    瞧!

答案 1 :(得分:0)

组件扫描导致问题。您的bean已经手动创建,但是Spring正在尝试创建另一个 EntityLoader,因为组件扫描正在提取您的@Component注释。

您可以告诉组件扫描(仅针对您的应用)忽略该类:

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