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
.)
精彩评论