使用 XML 配置覆盖 @Autowired 属性 注解
Override @Autowired property annotation with XML configuration
我有一个 class EntityLoader
用于使用 Hibernate 从 MySQL 数据库中获取一些数据。但是现在需要从两个不同的数据库(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">
到目前为止一切正常。为此,我做了以下更改:
- 从
component-scan
中排除 EntityLoader
以避免自动创建 EntityLoader
- 添加
mysqlSessionFactory
和 oracleSessionFactory
bean 定义
- 添加
mysqlEntityRepoLoader
和 oracleEntityRepoLoader
bean 定义
请注意,在 mysqlEntityRepoLoader
和 oracleEntityRepoLoader
中,我添加了属性 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
。我收到以下错误:
No qualifying bean of type [org.hibernate.SessionFactory] is defined:
expected single matching bean but found 2:
mysqlSessionFactory,oracleSessionFactory
如果我删除 @Autowired
一切正常。但我想维护它,因为这段代码是用于其他应用程序的通用库的一部分,通常情况下只从一个数据库加载。
有什么办法可以不去掉注解就完成吗?
导致问题的是组件扫描。您的 bean 已经手动创建,但是 Spring 正在尝试创建 另一个 EntityLoader
因为组件扫描正在获取您的 @Component
注释。
您可以告诉组件扫描(仅针对您的应用)忽略 class:
<context:component-scan ...>
<context:exclude-filter expression="com\.demo\.EntityLoader" type="regex" />
</context:component-scan>
如果您能够修改包含 EntityLoader 的库,则执行以下 2 步即可:
在 EntityLoader
中使您的 @Autowired
可选:
@Autowired(required=false)
在XML配置中,从自动装配候选人中排除mysqlSessionFactory和oracleSessionFactory beans,将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>
瞧!
我有一个 class EntityLoader
用于使用 Hibernate 从 MySQL 数据库中获取一些数据。但是现在需要从两个不同的数据库(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">
到目前为止一切正常。为此,我做了以下更改:
- 从
component-scan
中排除EntityLoader
以避免自动创建 EntityLoader - 添加
mysqlSessionFactory
和oracleSessionFactory
bean 定义 - 添加
mysqlEntityRepoLoader
和oracleEntityRepoLoader
bean 定义
请注意,在 mysqlEntityRepoLoader
和 oracleEntityRepoLoader
中,我添加了属性 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
。我收到以下错误:
No qualifying bean of type [org.hibernate.SessionFactory] is defined: expected single matching bean but found 2: mysqlSessionFactory,oracleSessionFactory
如果我删除 @Autowired
一切正常。但我想维护它,因为这段代码是用于其他应用程序的通用库的一部分,通常情况下只从一个数据库加载。
有什么办法可以不去掉注解就完成吗?
导致问题的是组件扫描。您的 bean 已经手动创建,但是 Spring 正在尝试创建 另一个 EntityLoader
因为组件扫描正在获取您的 @Component
注释。
您可以告诉组件扫描(仅针对您的应用)忽略 class:
<context:component-scan ...>
<context:exclude-filter expression="com\.demo\.EntityLoader" type="regex" />
</context:component-scan>
如果您能够修改包含 EntityLoader 的库,则执行以下 2 步即可:
在
EntityLoader
中使您的@Autowired
可选:@Autowired(required=false)
在XML配置中,从自动装配候选人中排除mysqlSessionFactory和oracleSessionFactory beans,将
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>
瞧!