JavaEE和CDI:了解@Observes

时间:2011-07-12 01:41:06

标签: java java-ee-6 cdi jboss-weld

我有原型org.jboss.weld.archetypes:jboss-javaee6-webapp:1.0.1.CR2,我尝试了解课程MemberListProducer

@RequestScoped
public class MemberListProducer
{
  @Inject @MemberRepository private EntityManager em;

  private List<Member> members;
  @Produces @Named public List<Member> getMembers() {return members;}

  public void onMemberListChanged(@Observes(notifyObserver = Reception.IF_EXISTS)
                                  final Member member){
    retrieveAllMembersOrderedByName();
  }

  @PostConstruct
  public void retrieveAllMembersOrderedByName()
  {
    //Criteria Query to fetch all members
    members = em.createQuery(criteria).getResultList();
  }
}

使用memberEventSrc.fire(newMember);从另一个类调用观察者,这似乎很清楚:一旦被触发,MemberListProducer就会更新成员列表。

但我不明白为什么在@RequestScoped Bean中完成此操作。在我的理解中,方法retrieveAllMembersOrderedByName无论如何都被每个请求调用。这个@Observes是不是应该更好地放在@ViewScoped@SessionScoped Bean中?它在这种情况下是否有影响?

2 个答案:

答案 0 :(得分:3)

@Observes的使用除了真实的实际用例外,还有更多的例子。在呈现响应之前考虑成员更改的可能性。 如果您删除它,我认为该网站不会正常工作。想想这样:

当请求开始时,会创建成员列表,并且它包含直到创建此请求范围bean的所有成员。稍后,您将保留新成员,因此需要更新此列表以呈现响应。

当您说列表是针对每个请求构建时,您认为正确,但这在开始时会发生。添加成员后,需要刷新它,不是吗? 如果这个方法不存在,那么响应将会过时(您在呈现新成员之前会呈现您拥有的列表),并且您需要一个额外的帖子或者获取新的成员列表。

@Observes将侦听器和事件源分离,就像观察者模式一样。因此,如果@Observes不存在,则需要将新成员显式添加到列表中,以便响应正确。

我希望我能正确理解你的问题。

答案 1 :(得分:0)

它的请求范围是因为它存储了每个请求的成员列表。如果您需要按会话存储此列表,请更改它。

但它看起来不对 - 你丢弃了观察者方法的member参数。