在 spring 中覆盖 bean 配置
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11833804/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
overriding bean configuration in spring
提问by Pokuri
Let's say I have two modules. One is core and another is core dependent implementation module. Core is a jar file for that dependent implementation module war.
假设我有两个模块。一个是核心,另一个是核心依赖的实现模块。Core 是该依赖实现模块 war 的 jar 文件。
In the core I have a bean defined like
在核心中,我定义了一个 bean
<bean id="x" class="com.pokuri.X">
<property name="y" ref="y"/>
<property name="z" ref="z"/>
</bean>
And that class has a method as follows
该类有一个方法如下
public class X{
public void doSomeJob(){
.......
}
}
this method is being called from some core classes. Now I need to alter the logic in that doSomeJob() method of X as per my core dependent implementation. So, I create a class like this
正在从一些核心类调用此方法。现在我需要根据我的核心依赖实现更改 X 的 doSomeJob() 方法中的逻辑。所以,我创建了一个这样的类
public class ExtX extends X{
@override
public void doSomeJob(){
// changed logic
}
}
and defined the bean with same id in another application context xml file like this.
并在这样的另一个应用程序上下文 xml 文件中定义了具有相同 id 的 bean。
<bean id="x" class="com.pokuri.ExtX">
<property name="y" ref="y"/>
<property name="z" ref="z"/>
</bean>
and we are building application context using contextConfigLocationcontext parameter in web.xmlspecifying value as classpath:springfolder.
我们正在使用contextConfigLocation上下文参数构建应用程序上下文,并将web.xml值指定为classpath:springfolder。
But in the core logic I am getting core bean instance only(i.e Xinstance) not ExtX. How can we override that bean definition and let system start using new extend bean definition?
但在核心逻辑中,我得到的不是核心 bean 实例(即X实例)ExtX。我们如何覆盖那个 bean 定义并让系统开始使用新的扩展 bean 定义?
And I heard that with same ID in different application context files will override first loaded bean definition with later loaded bean definition. Is there any prioritykind of attribute on bean definition to let ApplicationContext use highest priority one to consider over low priority one when beans with same ID were found.
而且我听说在不同的应用程序上下文文件中使用相同的 ID 会用稍后加载的 bean 定义覆盖第一个加载的 bean 定义。priority当找到具有相同 ID 的 bean 时,bean 定义上是否有任何类型的属性可以让 ApplicationContext 使用最高优先级的一个来考虑优先级低的一个。
回答by Biju Kunjummen
One way of overriding the bean definition is what you have indicated - to define it with the same id multiple times and the last bean definition with the same id is the one which takes effect. So if you ensure that ExtXis the last one loaded up, it should just work, and to ensure this you can do this in your war file, instead of loading up by saying classpath:springfolder, you can explicitly import the core configuration in your war's Spring config file and then override the bean this way:
覆盖 bean 定义的一种方法是您所指示的 - 多次使用相同的 id 定义它,并且最后一个具有相同 id 的 bean 定义生效。因此,如果您确保这ExtX是最后一个加载,它应该可以正常工作,并确保您可以在 war 文件中执行此操作,而不是说加载classpath:springfolder,您可以在 war 的 Spring 配置文件中显式导入核心配置然后以这种方式覆盖 bean:
<import resource="core-resource.xml"/>
<bean id="x" class="com.pokuri.ExtX">
<property name="y" ref="y"/>
<property name="z" ref="z"/>
</bean>
This will ensure that your overridden bean is the one which takes effect.
这将确保您的覆盖 bean 是生效的 bean。
There is no priority/order field that you can make use of here though - if you want you can load up all bean definitions of a type by providing Map<String,X>as a parameter, and sort it by expecting an order property and use it that way, but there is lot more work to it.
虽然这里没有您可以使用的优先级/顺序字段 - 如果您愿意,您可以通过提供Map<String,X>作为参数来加载某个类型的所有 bean 定义,并通过期望一个 order 属性对其进行排序并以这种方式使用它,但是还有很多工作要做。
A second approach is described here: Overriding the bean defined in parent context in a child context
这里描述了第二种方法:Overriding the bean defined in parent context in a child context

