在春天覆盖bean配置

时间:2012-08-06 18:25:58

标签: spring inversion-of-control

假设我有两个模块。一个是核心,另一个是核心相关实现模块。 Core是该依赖实现模块之战的jar文件。

在核心中我有一个定义为

的bean
<bean id="x" class="com.pokuri.X">
 <property name="y" ref="y"/>
 <property name="z" ref="z"/>
</bean>

该课程的方法如下

public class X{

  public void doSomeJob(){
   .......
  }   

}

从一些核心类调用此方法。现在我需要根据我的核心依赖实现来改变X的doSomeJob()方法中的逻辑。所以,我创建了一个像这样的类

public class ExtX extends X{

  @override
  public void doSomeJob(){
    // changed logic
  }

}

并在另一个应用程序上下文xml文件中定义了具有相同id的bean。

<bean id="x" class="com.pokuri.ExtX">
     <property name="y" ref="y"/>
     <property name="z" ref="z"/>
</bean>

我们正在使用contextConfigLocation中的web.xml上下文参数构建应用程序上下文,并将值指定为classpath:springfolder

但是在核心逻辑中我只获得了核心bean实例(即X实例)而不是ExtX。我们如何覆盖该bean定义并让系统开始使用新的扩展bean定义?

我听说在不同的应用程序上下文文件中使用相同的ID将覆盖第一个加载的bean定义以及后来加载的bean定义。 bean定义中是否有任何priority类属性,以便在找到具有相同ID的bean时,让ApplicationContext使用最高优先级的属性来考虑低优先级。

1 个答案:

答案 0 :(得分:13)

重写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>

这将确保重写的bean是生效的bean。

此处没有可以使用的优先级/订单字段 - 如果您希望可以通过提供Map<String,X>作为参数来加载类型的所有bean定义,并通过预期订单对其进行排序财产并以这种方式使用它,但还有很多工作要做。

此处描述了第二种方法:Overriding the bean defined in parent context in a child context