开发者

Java EE 6 and CDI

I'm just starting learning CDI and Java EE 6 but I found this piece of code that I want to fully understand.

@Stateful
@Model
public class MemberRegistration {
   @Inject
   private EntityManager em;

   @Inject
   private Event<Member> memberEventSrc;

   private Member newMember;

   @Produces
   开发者_Python百科@Named
   public Member getNewMember() {
      return newMember;
   }
}

Then... I saw that a jsf page referenced this newMember object like this:

<h:inputText value=#{newMember.name}/>

So my question is : It doesn't matter if I put an @Named annotation inside an variable of any object, it will be accessible anyway from JSF code? Also, what's the usage of @Produces in this case, and finally is @Stateful preferred over @Stateless in Java EE 6? If that's the case why?


Despite its simplicity this bean sure does a lot of things ;)

Either the @Named (CDI) or @ManagedBean (JSF-native) annotation is required to make a bean known to JSF. However, Java EE has the concept of stereotypes, which are a kind of composite annotations that combine a number of other ones.

In this case @Model is such a stereotype, it combines @Named and @RequestScoped.

@Produces annotates a factory method; a method that knows where to get an instance of some type from. It can be combined with a so-called qualifier annotation, e.g. @Foo, after which you can use that annotation to inject something in some bean. In this case however it's combined with @Named, which makes newMember available to JSF. Instead of creating the bean as would happen when e.g. an @RequestScoped bean is encountered first, under the covers the getNewMember() method will be called when JSF wants an instance. See Dependency Injection in Java EE 6 for more info.

@Stateful is normally not preferred over @Stateless when used standalone. @Stateless beans are pooled and execute one method for a client (typically in a transactional context). Their stateful counterpart is not pooled and without CDI, the caller has to keep track of its life-cycle (by eventually calling an @Remove annotated method). Here, the bean is also assigned a scope (request, via @Model), so the container will take care of that.

The likely reason for using this annotation here is probably to make the bean's methods transactional. Although the fragment as given doesn't show its usage I guess there's a version of this class with more methods that make use of the EntityManager. Transactions will come into play there.

(Note, combining annotations this way gives the Java EE developer lots of power, but it does put several concerns in one bean which is contrary to the mantra that a bean should do one thing and do that well. An alternative is an @Model annotated bean focussing on view concerns only, that's injected with @Stateless beans that encapsulate the business logic instead of an EntityManager.)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜