我正在使用Spring 3创建一个Web应用程序,并希望利用Spring Expression Language的强大功能,但遇到了问题。我需要将我的一个bean上的属性值设置为另一个bean上的方法调用的结果。我知道我可以这样做,但问题是该方法调用的结果可能会在bean初始化后发生变化,我需要该属性来反映变化。例如:
<beans>
...
<bean name="guestList" class="java.util.ArrayList"></bean>
<bean name="party" class="some.custom.class.Party">
<property name="numberOfGuests" value="#{guestList.size()}" />
</bean>
...
</beans>
据我所知,numberOfGuests
字段是第一次访问party
字段时设置的。但是在访问party
字段后,访客数量可能会发生变化,我需要numberOfGuests
字段来反映这一点。有没有办法在我需要更新值时重新初始化我的应用程序中的numberOfGuests
字段?
这只是一个示例,直接访问guestList
bean对我的具体情况不起作用。
答案 0 :(得分:2)
如果你将范围设置为原型,那么每次Spring加载你的bean时,它应该重新计算访客列表的大小:
<bean name="party" class="some.custom.class.Party" scope="prototype">
因此,party
成为原型,但guestList
可以保持单身(这是默认范围)。
虽然有一个问题:如果你有另一个bean,比如partyHost
(这是一个单身人士),并且注入了party
(这是一个原型),partyHost
将永远不会得到party
的另一个实例,因为partyHost
是一个单例,只有一次注入依赖项。因此,为了实现这一点,所有需要更新的guest虚拟机列表大小的bean以及引用它们的所有bean等都必须是原型。
或者,你必须直接通过他们的API询问Spring。如果您使用API,您可以随时调用它并获取原型bean的新实例,从而获得更新的访客列表大小。
applicationContext.getBean("myPrototype");
但是,如果可以,最好避免使用Spring API。通常,开发人员不希望与DI框架耦合。
答案 1 :(得分:0)
#{guestlist.size()}的示例仅设置属性的初始值,而不是用于使其保持最新的策略。假设您没有使用延迟加载,Spring会在启动时从应用程序上下文中实例化Spring托管bean。从那时起,由开发人员来处理更新属性值。
答案 2 :(得分:0)
我猜最简单的做法是将列表(guestList
)注入bean并在每次需要.size()
时从Java代码手动调用其numberOfGuests
方法,即:
package some.custom.class;
public class Party {
private List<?> guestList;
// getter & setters
public int getNumberOfGuests() {
return guestList!=null ? guestList.size() : 0;
}
}
和...
<bean name="party" class="some.custom.class.Party">
<property name="guestList" ref="guestList"/>
</bean>