4

I have the archetype org.jboss.weld.archetypes:jboss-javaee6-webapp:1.0.1.CR2 and I try to understand the class 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();
  }
}

The observer is invoked from another class with memberEventSrc.fire(newMember);, this seems clear: Once fired, the MemberListProducer updates the list of members.

But I don't understand why this is done in a @RequestScoped Bean. In my understanding the method retrieveAllMembersOrderedByName is anyway called by each request. Should this @Observes not be better placed in a @ViewScoped or @SessionScoped Bean? Does it have an effect in this case at all?

Thor
  • 6,607
  • 13
  • 62
  • 96

2 Answers2

4

The use of @Observes there is more of an example than a real, practical use case. Consider the possibility of members changing before you render your response. I don't think the website would work correctly if you removed it. Think about it like this:

When the request starts, the list of members is created and it contains all the members up to the moment of creation of this request scoped bean. Later, you persist a new member, so this list needs to be updated to render the response.

You think correctly when you say that the list is built for each request, however this happens at the beginning. After you add a member, you need to refresh it, don't you? If this method weren't there, the response would be outdated (you'd render the list you had before you persisted the new member), and you would need one extra post or get to fetch the new list of members.

@Observes decouples listeners and event sources much like the observer pattern. So if the @Observes isn't there, you would need to explicitly add the new member to the list so that the response is correct.

I hope I understood your question correctly.

arg20
  • 4,893
  • 1
  • 50
  • 74
  • Please have in mind like I said that this example is theoretical and can be optimized. You don't usually keep all members in memory and if you do it's probably either @applicationscoped or a Singleton, etc. I'm sure you already know that tho hehe. – arg20 Jul 18 '11 at 08:40
1

It's request scoped because it stores a list of members per request. If you need this list to be stored per-session, then change it.

But it looks wrong - you are discarding the member arguments of the observer method.

Bozho
  • 588,226
  • 146
  • 1,060
  • 1,140
  • Actually I don't *need* it (and it's not my snippet, it's from the archetype example). I just want to understand it. If the member list is created for each request, what is the reason for the `onMemberListChanged` method? – Thor Jul 16 '11 at 08:54
  • well, multiple members can be registered within one request, theoretically. – Bozho Jul 16 '11 at 08:59
  • Theoretically, but in this example the bean seams to be only a facade to access the list of members and `onMemberListChanged` has no effect in my opinion. – Thor Jul 16 '11 at 13:03
  • 2
    >>...but in this example the bean _seams_...<< - I really like this typo, it almost seems sorry >>seams<< like a hidden token for all Seam users :-))) – Jan Groth Jul 18 '11 at 07:05