繁体   English   中英

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

[英]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无法做到这一点; 当获取myNewBeanmyBeanFallbackmyOldBean )属性正确地构造为构造函数中指定的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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM