As I am learning JSF2, I realized I am not sure what the backing components should be. From design point of view, what is the difference between EJBs and @ManagedBeans
?
In the end I am going to use JPA, so EJB is a natural choice for business layer. Is it a good practice to use EJB directly from JSF (as explained here)?
At the moment I'm leaning towards using @ManagedBeans
for components which don't need access to business layer (e.g. view help开发者_JAVA技巧ers) or deal with request/session data. For other purposes, e.g. listing something in a grid, I would directly access EJB.
Is this a good design? Shall I use @ManagedBeans
for all backing beans for the sake of clean layer separation, even if in some cases they only delegate to EJB?
Very valid question, but I guess the answer depends on the "strictness" of the approach for your project. There is indeed a bit of redundancy between JSF backing bean and EJB as both implement some business logic.
In a ideal usage of JSF features with converters
, rendered
, validator
, etc. the backing bean could indeed be clean business logic code. But in practice some presentation-related logic frequently leaks in it.
This presentation-related logic should ideally not be in a EJB. This presentation-related logic may depend on the faces package, but not necessary. It's what it does that make it presentation-related or not.
A unified component model has some advantages though. And it's the approach taken by Seam and Spring. In both case, business component with declarative transaction, etc. can be used directly in JSF (Spring does not use EJB but provide a similar model). EJB purist would however say that you should dissociate the two.
So to me it's ultimately a question of taste and size of the project. I can imagine that for a small/medium project using EJB in JSF works fine. For bigger project where this strictness is critical, make sure you don't screw the layers.
In Java EE 6 there is some overlap between the various managed beans: JSF managed beans (@ManagedBean), CDI managed beans (@Named) and EJB beans (@Stateless, @Statefull, @Singleton).
In the view layer I don't see any particular advantage for sticking with @ManagedBean. The CDI variant @Named seems to be able to do the same and more, e.g. provide you with access to the conversion scope.
The current thinking seems to be that eventually the EJB component model will also be retrofitted as a set of CDI annotations. Especially expert group member Reza Rahman frequently hints at this. See e.g. Dependency Injection in Java EE 6 - Part 1
For the time being this has not happened, so EJB beans remain the easiest place to put business logic, especially when JPA is used for persistence.
Nevertheless, whether or not CDI will obtain the capabilities of EJB, IMHO it's still a best practice to use a separate bean for the "backing bean" concept and a separate bean for the "business logic".
The backing bean can be really slim, just containing some references to model objects and services (EJBs). Action Methods of the backing bean can delegate almost directly to the services, but their added value is in providing the user with feedback (adding FacesMessages upon success or failure) and doing small UI modifications (e.g. setting a boolean to false that displayed some dialog).
The Services (business logic) should not know anything about any particular presentation. They should be equally well usable from JSF backing beans, JAX-RS, Servlets, standalone Java SE remote clients or whatever.
Even if all beans would become CDI beans, then this does not change this basic division of responsibility.
Interesting article, didn't knew about that. However, to me this article smells more like a rant towards JSF managed beans. It also tight-couples EJB with JSF. It's maybe interesting in small (personal) applications, but likely not in real world SOA applications where you'd like to have full control over the EJB's been serviced.
As to which one to use for what, I would just stick to @ManagedBean
to denote a JSF model --which is tied to one or more specific JSF views. You can perfectly use @EJB
s for non-JSF specific business logic and/or datamodels. You can inject @EJB
s in a JSF model and delegate it in action methods and maybe also getters/setters, but you should not do the other way round, i.e. do not define the JSF model in an @EJB
, this leads to tight coupling and would make @EJB
s unuseable outside the JSF context. As far, your design sounds good, as long as you watch to not import anything from javax.faces
package in the @EJB
class.
By calling EJB from your XHTML, you are introducing tight coupling between the choice of implementation in the view and business tier.
If you use a managed bean to call an EJB, [or even, put in a business delegate], you will be able to change out your business tier completely to Spring without affecting the view layer (XHTML).
Is is technically possible, and very easy for you to (JSR 299) be able to use EJB as your managed bean, and that is probably what these vendors want you to do - get glued to specifics. But whether that is a correct thing to do? - No.
精彩评论