[英]Override @Autowired property annotation with XML configuration
I've a class EntityLoader
that's used to fetch some data from a MySQL database using Hibernate. 我有一个
EntityLoader
类,它用于使用Hibernate从MySQL数据库中获取一些数据。 But now the need is to fetch data from two different databases (MySQL and Oracle in this case). 但现在需要从两个不同的数据库(在这种情况下是MySQL和Oracle)中获取数据。 So I want to have two beans of
EntityLoader
but injecting a different SessionFactory
in each one. 所以我希望有两个
EntityLoader
bean,但每个bean都注入一个不同的SessionFactory
。
EntityLoader
is defined as follows: 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;
}
}
And the context configuration is: 上下文配置是:
<context:component-scan base-package="com.demo" />
<bean id="mysqlSessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
So far it works fine. 到目前为止它工作正常。 Over this I have done the following changes:
在此我做了以下更改:
EntityLoader
from component-scan
in order to avoid the auto creation of a EntityLoader component-scan
中排除EntityLoader
以避免自动创建EntityLoader mysqlSessionFactory
and oracleSessionFactory
bean definitions mysqlSessionFactory
和oracleSessionFactory
bean定义 mysqlEntityRepoLoader
and oracleEntityRepoLoader
bean definitions mysqlEntityRepoLoader
和oracleEntityRepoLoader
bean定义 Note that in mysqlEntityRepoLoader
and oracleEntityRepoLoader
I've added the attribute autowired="no"
hoping that this would tell Spring to not autowire the SessionFactory
and use the defined ref instead. 请注意,在
mysqlEntityRepoLoader
和oracleEntityRepoLoader
我添加了属性autowired="no"
希望这会告诉Spring不要自动装配SessionFactory
并使用定义的ref。
The resulting configuration is: 结果配置为:
<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>
But it seems that Spring is trying first to autowire the SessionFactory
in any case. 但似乎Spring在任何情况下都首先尝试自动装配
SessionFactory
。 I get the following error: 我收到以下错误:
No qualifying bean of type [org.hibernate.SessionFactory] is defined: expected single matching bean but found 2: mysqlSessionFactory,oracleSessionFactory
没有定义[org.hibernate.SessionFactory]类型的限定bean:期望的单个匹配bean但找到2:mysqlSessionFactory,oracleSessionFactory
If I remove the @Autowired
all works fine. 如果我删除
@Autowired
一切正常。 But I would like to maintain it, as this code is part of a generic lib used for other apps where the usual case is to load only from one database. 但我想维护它,因为此代码是用于其他应用程序的通用库的一部分,其中通常的情况是仅从一个数据库加载。
Is there any way to accomplish it without removing the annotation? 有没有办法在不删除注释的情况下完成它?
If you are able to modify your lib which contains EntityLoader, following these 2 step will do the trip : 如果您能够修改包含EntityLoader的lib,则执行以下两步操作:
In EntityLoader
make your @Autowired
optional: 在
EntityLoader
让@Autowired
可选:
@Autowired(required=false) @Autowired(所需=假)
In XML configuration, exclude mysqlSessionFactory and oracleSessionFactory beans from autowire candidates, add autowire-candidate="false"
to each sessionFactory: 在XML配置中,从autowire候选者中排除mysqlSessionFactory和oracleSessionFactory bean,将
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>
Voilà! 瞧!
It's the component-scan that's causing problems. 这是导致问题的组件扫描。 Your beans are already manually created, but Spring is trying to create another
EntityLoader
because the component scan is picking up your @Component
annotation. 您的bean已经手动创建,但Spring正在尝试创建另一个
EntityLoader
因为组件扫描正在拾取您的@Component
注释。
You can tell the component scan (for just your app) to ignore that class: 您可以告诉组件扫描(仅针对您的应用)忽略该类:
<context:component-scan ...>
<context:exclude-filter expression="com\.demo\.EntityLoader" type="regex" />
</context:component-scan>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.