我有以下课程,我试图通过春季实例化。
class MyBean{
MyBean myBeanFallback;
MyDataObject myDataObject;
public void setMyBeanFallback(MyBean myBeanFallback){
this.myBeanFallback = myBeanFallback;
}
MyBean(MyDataObject myDataObject){
this.myDataObject = myDataObject;
}
}
以下是我尝试加载的弹簧配置:
<bean name="myNewBean" class="MyBean"
scope="prototype">
<constructor-arg index="0" type="MyDataObject" >
<null />
</constructor-arg>
<property name="myBeanFallback" ref="myOldBean" />
</bean>
<bean name="myOldBean" class="MyBean"
scope="prototype">
<constructor-arg index="0" type="MyDataObject" >
<null />
</constructor-arg>
</bean>
在我的应用程序代码中,我可以实例化具有数据且没有回退的myOldBean。 否则我可以实例化myNewBean,它有数据并且还有myOldBean作为回退,而后者又需要具有相同的myDataObject
getNewBean(MyData mydata){
return (MyBean) context.getBean("myNewBean", new Object[] { mydata });
}
getOldBean(MyData mydata){
return (MyBean) context.getBean("myOldBean", new Object[] { mydata });
}
我现在面临的问题是,在获取myNewBean时,后备getNewBean不会被mydata填充,而是取为空。
关于如何解决这个问题的任何指示?
答案 0 :(得分:1)
你不能用Spring做到这一点;当您获得myNewBean
时,myBeanFallback
(myOldBean
)属性已根据构造函数中指定的null
值正确设置,并且您无法更改此行为,因为myBeanFallback
不是使用FactoryBean.getBean()
构建的,而是自动装配的
也许以这种方式使用工厂可以是一个解决方案:
class MyBeanFactory {
public getNewBean(MyData mydata){
MyBean myBean = (MyBean) context.getBean("myNewBean", new Object[] { mydata });
MyBean myBeanFallback = getOldBean(myData);
myBean.setMyBeanFallback(myBeanFallback);
return myBean;
}
public getOldBean(MyData mydata){
return (MyBean) context.getBean("myOldBean", new Object[] { mydata });
}
}
和beans.xml
<bean name="myNewBean" class="MyBean" scope="prototype" />
<bean name="myOldBean" class="MyBean" scope="prototype" />
答案 1 :(得分:0)
从来没有做过这样的事情,但这里是我的$ .05:因为你的myOldBean定义是作为原型的范围,在Spring内部它已知具有该名称,但它是null。因此,当您创建myNewBean实例时,它将使用该空引用。
我认为Spring并不打算以这种方式使用。我可能错了,但是整个构造函数将值传递给getBean是绕过Spring的目标之一:让spring配置和链接你的对象,就像你在xml文件中指定的那样,将xml与在代码中创建bean混合会导致像你的情况......
所以我的建议是:尝试将整个配置放在春天。
答案 2 :(得分:0)
@bellabax有正确的想法。
另一点是你可以使用FactoryBean(link to Spring manual)来自定义scope = prototype的bean的构造。所以你可以按原样保留myOldBean,然后通过这样的方式自定义myNewBean的构造:
<bean name="myNewBean" class="MyNewFactoryBean" scope="prototype">
<property name="myData"><!-- however you want to provide the value for this --></property>
</bean>
然后是FactoryBean实现:
public class MyNewFactoryBean implements FactoryBean<MyBean> {
protected MyData myData;
public void setMyData(MyData d) {
myData = d;
}
@Override
public MyBean getObject() throws Exception {
MyBean myBean = new MyBean();
myBean.setMyBeanFallback(context.getBean("myOldBean", new Object[] { myData }));
return myBean;
}
@Override
public Class<MyBean> getObjectType() {
return MyBean.class;
}
....
}
当你这样做时,你可以(在你的代码中稍后)像往常一样做context.getBean("myNewBean")
之类的事情,它将从MyNewFactoryBean调用你的自定义实例化逻辑。