![](/img/trans.png)
[英]Spring: How to make class a bean if one constructor-arg is a ref bean but another is not?
[英]Passing spring constructor-arg to another ref bean
我正在尝试在春季开设的下一堂课。
class MyBean{
MyBean myBeanFallback;
MyDataObject myDataObject;
public void setMyBeanFallback(MyBean myBeanFallback){
this.myBeanFallback = myBeanFallback;
}
MyBean(MyDataObject myDataObject){
this.myDataObject = myDataObject;
}
}
以下是我正在尝试加载的spring配置:
<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。 否则我可以实例化具有数据并且还具有myOldBean作为后备的myNewBean,这又需要具有相同的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,而是采用null。
关于如何解决这个问题的任何指针?
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" />
从来没有做过这样的事情,但是这里是我的$ .05:因为myOldBean定义的范围是原型,所以在Spring内部它以该名称而为人所知,但它为null。 因此,当您创建myNewBean实例时,它将使用该null引用。
我不认为Spring打算那样使用。 我可能是错的,但是整个构造函数将值传递给getBean是绕过Spring的目标之一:让spring像在xml文件中指定的那样配置和链接您的对象,将xml与在代码中创建Bean混合会导致混乱你的情况...
因此,我的建议是:尝试在春季放置整个配置。
@bellabax有正确的想法。
另一点是,您可以使用FactoryBean ( 指向Spring手册的链接 )来自定义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")
一样(稍后在代码中)执行诸如context.getBean("myNewBean")
,它将从MyNewFactoryBean调用自定义实例化逻辑。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.