将spring constructor-arg传递给另一个ref bean

时间:2013-08-28 19:32:09

标签: java spring

我有以下课程,我试图通过春季实例化。

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填充,而是取为空。

关于如何解决这个问题的任何指示?

3 个答案:

答案 0 :(得分:1)

你不能用Spring做到这一点;当您获得myNewBean时,myBeanFallbackmyOldBean)属性已根据构造函数中指定的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有正确的想法。

另一点是你可以使用FactoryBeanlink 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调用你的自定义实例化逻辑。

相关问题