0

我有以下课程,我试图通过 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,而是采用 null。

有关如何解决此问题的任何指示?

4

3 回答 3

1

你不能用 Spring 做到这一点。当您获取时myNewBeanmyBeanFallback( 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" />
于 2013-08-28T19:50:56.313 回答
0

@bellabax 有正确的想法。

另一点是您可以使用FactoryBean指向 Spring 手册的链接)来自定义范围 = 原型的 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 调用你的自定义实例化逻辑。

于 2013-08-28T20:09:18.920 回答
0

从来没有做过这种事情,但这是我的 $.05:因为你的 myOldBean 定义的范围是原型,在 Spring 内部它以该名称为人所知,但它为空。因此,当您创建 myNewBean 实例时,它将使用该空引用。

我不认为 Spring 打算以这种方式使用。我可能错了,但是将值传递给 getBean 的整个构造函数绕过了 Spring 的目标之一:让 spring 像您在 xml 文件中指定的那样配置和链接您的对象,将 xml 与在代码中创建 bean 混合会导致像你的情况...

所以我的建议是:尝试将整个配置放在 spring 中。

于 2013-08-28T19:52:41.023 回答