我尝试在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”。
请帮我解决这个问题。
答案 0 :(得分:2)
execute
中的{p> test4
不会被调用,因为m3被声明为lazy-init="true"
。依赖链如下:
所以在启动时,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在启动时默认不应该进行任何初始化。现在,依赖链是:
因此,当您请求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编写代码......