Java 将spring构造函数arg传递给另一个refbean
我有下面的类,我正试图通过spring实例化它Java 将spring构造函数arg传递给另一个refbean,java,spring,Java,Spring,我有下面的类,我正试图通过spring实例化它 class MyBean{ MyBean myBeanFallback; MyDataObject myDataObject; public void setMyBeanFallback(MyBean myBeanFallback){ this.myBeanFallback = myBeanFallback; } MyBean(MyDataObject myDataObject){
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>
我现在面临的问题是,在获取myNewBean时,回退getNewBean不使用mydata填充,而是使用null
有关于如何解决这个问题的指示吗?你不能用Spring解决这个问题;当您获得
myNewBean
时,myBeanFallback
(myeldbean
)属性按照构造函数中指定的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" />
从未做过这种事情,但我的$0.05是这样的:因为您的myOldBean定义的范围是作为原型的,所以在Spring内部,它以该名称命名,但它是空的。因此,当您创建myNewBean实例时,它将使用该空引用 我不认为Spring是打算这样使用的。我可能错了,但是整个构造函数向getBean传递值是绕过了Spring的目标之一:让Spring像您在xml文件中指定的那样配置和链接您的对象,将xml与在代码中创建bean混合在一起将导致像您的情况一样的混乱
所以我的建议是:尝试将整个配置放在春季。@bellabax的想法是正确的 关于这一点的另一点是,您可以使用()来定制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;
}
....
}
公共类MyNewFactoryBean实现FactoryBean{
受保护的MyData MyData;
公共void setMyData(MyData d){
myData=d;
}
@凌驾
公共MyBean getObject()引发异常{
MyBean MyBean=新的MyBean();
setMyBeanFallback(context.getBean(“myOldBean”,新对象[]{myData}));
返回myBean;
}
@凌驾
公共类getObjectType(){
返回MyBean.class;
}
....
}
当您这样做时,您可以(稍后在代码中)像平常一样执行
context.getBean(“myNewBean”)
之类的操作,它将从MyNewFactoryBean调用您的自定义实例化逻辑。我在这里怎么做?您可以帮助使用示例bean xml吗?他想创建myeldbean
bean(作为myBeanFallback
属性),并将相同的mydata
arg传递给getNewBean(mydata)
。OP希望将mydata
arg传播到myOldBean
上下文中,以创建myNewBean
Yust一个问题:为什么不使用相同的工厂来设置myBean.setMyBeanFallback()?这是我的豆子,就像我的豆子一样。。。但是,除此之外,我还考虑了factorybean,但MyNewFactoryBean.myData应该由应用程序代码提供。您必须编写MyNewFactoryBean fb=context.getBean(“myNewBean”);fb.设置mydata(mydata)代码>并且您失去了使用自动布线的真正方式。。。这个问题本身使用了一种奇怪的spring注入功能way@bellabax有趣-是的,你是对的,在问题本身中,他使用了Spring提供的配置组合,但也传递了myData。我同意他需要决定配置数据应该来自哪里。如果构造函数arg是从代码中传入的,那么spring连接的大部分好处就失去了。然而,如果他试图定制构建过程,FactoryBean是正确的工具。我将看看是否可以在这里修改我的答案,以便更详细地阐述它;每次使用context.getBean()都是天生的。由于在我的应用程序中的(个人)考虑,我用MyBeanFactory接口和没有FactoryBean的相关实现解决了问题,因为我和OP有同样的问题,因为args来自应用程序代码。是的,我明白你的意思。另一点是,如果可以实现MyBean(mydataobjectd)
asMyBean b=newmybean();b、 setMyDataObject(…)
,实际上您可以使用spring连接来确定涉及的类并进行构造(使用FactoryBean),然后仍然设置MyDataObject。这可能是最好的分割方法,所以我的问题是Spring配置的意义是什么?您试图允许通过SpringConfig定制的是什么?(请看下面bellabax和我之间的对话)你想通过提供不同的类来覆盖MyBean的实现吗?可能是的。此外,我还想从我做起所有的构造,注入正确的依赖项并填充所需的参数。MyData是数据对象,我还有多个其他依赖项要注入myBean中,这也是我希望通过spring实现的
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;
}
....
}