MethodInvokingFactoryBean-方法未被调用

时间:2012-04-02 19:03:38

标签: java spring

我尝试在MethodInvokingFactoryBean上编写一个测试程序,其中有两个bean声明如下。

<bean id="test2" class="test3">
</bean>

<bean id="m2" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean" lazy-init="false" depends-on="test4">
    <property name="targetObject"><ref local="test2"></ref></property>
    <property name="targetMethod"><value>execute</value></property>
    <property name="arguments">
       <list>
        <value>abc</value>
        <ref local="test4"></ref>
       </list>
    </property>
</bean>

<bean id="test4" class="test5"></bean>
<bean id="m3"class="org.springframework.beans.factory.config.MethodInvokingFactoryBean" lazy-init="true">
    <property name="targetObject"><ref local="test4"></ref></property>
    <property name="targetMethod"><value>execute</value></property>
    <property name="arguments">
       <list>
          <value>xyz</value>
        </list>
        </property>
</bean>

我通过以下方式获取bean:

test3 obj3 =  (test3) _context.getBean("test2");

这里的用例是, 在test2中执行方法execute之前,我应该能够执行位于bean“test4”上的方法execute,因为“test4”是我运行execute方法的参数之一“TEST2”。

而且,我需要做一切lazy-init = true

我试过上面的内容,但是在test2中执行Method之前没有调用test4中的方法“execute”。

请帮我解决这个问题。

1 个答案:

答案 0 :(得分:2)

execute中的{p> test4不会被调用,因为m3被声明为lazy-init="true"。依赖链如下:

  • eager bean test2是独立的
  • eager bean test4是独立的
  • eager bean m2取决于test2和test4
  • lazy bean m3取决于test4

所以在启动时,Spring初始化test2,test4然后m2。它不会做m3,因为它很懒惰。然后,当您向上下文请求bean test2时,它会看到test4已经完全初始化并且只返回它。

现在,你说你需要lazy-init="true"这一切,但事实上你的大多数豆子都很渴望。是否会让一切变得非常懒惰并以这种方式改变它以满足您的要求?

<bean id="test2" class="test3" lazy-init="true" depends-on="m2">
</bean>

<bean id="m2" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean" lazy-init="true" depends-on="m3">
    <property name="targetObject"><ref local="test2"></ref></property>
    <property name="targetMethod"><value>execute</value></property>
    <property name="arguments">
       <list>
        <value>abc</value>
        <ref local="test4"></ref>
       </list>
    </property>
</bean>

<bean id="test4" class="test5" lazy-init="true"></bean>
<bean id="m3"class="org.springframework.beans.factory.config.MethodInvokingFactoryBean" lazy-init="true">
    <property name="targetObject"><ref local="test4"></ref></property>
    <property name="targetMethod"><value>execute</value></property>
    <property name="arguments">
        <list>
          <value>xyz</value>
        </list>
    </property>
</bean>

这样一切都是lazy-init所以Spring在启动时默认不应该进行任何初始化。现在,依赖链是:

  • lazy bean test4是独立的
  • lazy bean m3取决于bean test4
  • lazy bean m2取决于bean test2,m3和test4
  • lazy bean test2取决于bean m2

因此,当您请求bean test2时,将触发m2,m3和test4的初始化。它并不漂亮,因为test2和m2之间存在循环依赖关系,但它应该可以工作。

无论如何,你的设置非常复杂,如果你不能简化它,我认为你正处于Spring开始妨碍你的方向。我建议你用Java编写一个隐藏这些依赖项管理的服务,这样你就可以删除所有这些XML并简单地放一个简单直接的bean声明。与此类似的东西,其中test2Factory隐藏了所有的丑陋:

<bean id="test2Factory" class="test2FactoryClass">
   <property name="test4"><bean class="test5"/></property>
</bean>

<bean id="test2" factory-bean="test2Factory" factory-method="getInstance"/>

<强>更新

这变得很乱,你可以试着宣布一些人工豆来打破循环:

<bean id="rawTest2" class="test3" lazy-init="true">
</bean>

<bean id="m2" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean" lazy-init="true" depends-on="m3">
    <property name="targetObject"><ref local="rawTest2"></ref></property>
    <property name="targetMethod"><value>execute</value></property>
    <property name="arguments">
       <list>
        <value>abc</value>
        <ref local="test4"></ref>
       </list>
    </property>
</bean>

<bean id="test2" class="org.springframework.beans.factory.config.PropertyPathFactoryBean" lazy-init="true" depends-on="m2">
    <property name="targetBeanName" value="rawTest2"/>
    <property name="propertyPath" value=" "/><!-- One space inside quotes -->
</bean>

<!-- m3 and test4 stay the same as before -->

虽然此时我只想用Java编写代码......