使用SpEL更新Spring bean属性的值

时间:2010-11-19 19:49:39

标签: java spring expression

我正在使用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对我的具体情况不起作用。

3 个答案:

答案 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>