将xml定义中的其他bean添加到已在运行时初始化的应用程序上下文中

时间:2016-06-30 05:11:11

标签: spring spring-mvc dependency-injection applicationcontext

正如您在下面的代码中看到的, 我想分别将两个xmls A.xmlB.xml加载到ApplicationContext。我目前正在使用父/子上下文关系。但是当我这样做时,我得到了类C的不同实例。

有没有办法获取在加载C时初始化并在A.xml中使用相同实例的类B.xml的实例?

A.XML - >

<import resource="classpath*:c.xml" />
<bean id="testA" class="com.TestA">
    <property name="testC">
        <ref bean="cBean" />
    </property>
</bean>

B.XML - &GT;

<import resource="classpath*:c.xml" />
<bean id="testB" class="com.TestB">
    <property name="testC">
        <ref bean="cBean" />
    </property>
</bean>

C.xml - &GT;

<bean id="cBean" class="com.TestC">
</bean>

以下是相关代码:

context = new ClassPathXmlApplicationContext("A.xml");  

context = new ClassPathXmlApplicationContext(new String[]{B.xml}, context);

((AbstractApplicationContext) context).registerShutdownHook();

输出 - &GT;

  In Test A-->com.TestC@1df177.
  In Test B-->com.TestC@1ad8c79

2 个答案:

答案 0 :(得分:1)

A和B组成一个分层上下文。这是一个普通的上下文,这里包含2个bean A和B,而B是一个包含2个bean的子上下文,B和C的副本,可以从其父上下文访问bean。

分层上下文是一种广泛使用的功能,但您不能从子上的父上下文中复制bean。如果这样做,来自父和子的bean将对任何重复的bean使用不同的副本 - &gt;你在这里得到什么。

如何解决:

最简单的方法是不在B中导入C.这样,bean C只位于A中,但由于父子关系,仍然可以从B访问。

B.XML - &GT;

{"$ifNull": ["$recipientDetails.firstname", ""]}

答案 1 :(得分:0)

首先,您不需要使用3个不同的xml文件。您可以执行以下操作;

<bean id="cBean" class="com.TestC">
</bean>
<bean id="testA" class="com.TestA">
    <property name="testC">
        <ref bean="cBean" />
    </property>
</bean>
<bean id="testB" class="com.TestB">
    <property name="testC">
        <ref bean="cBean" />
    </property>
</bean>

这意味着TestC,TestA,TestB都是单例bean,其中TestC bean由Property / Setter注入TestA和TestB。

现在,如果您希望TestC与TestA和TestB具有相同的实例,则执行以下操作;

public class TestA{
   //Global Declaration
   private TestC testC;
   // Setter Injection
   public void setTestC(TestC testC){
      this.testC = testC
   }
   //some methods which will be called from main
}

public class TestB{
   //Global Declaration
   private TestC testC;
   // Setter Injection
   public void setTestC(TestC testC){
      this.testC = testC
   }
   //some methods which will be called from main
}