Andy is a software developer of over 15 years experience and currently specializes in Java with Seam, Hibernate, Wicket and Spring as well as JSF, JPA and CDI. His own blog at www.andygibson.net is host to his Open Source projects DataValve , Knappsack and JTexGen and provides a home for his articles and tutorials on Java and Java EE of which he is a big supporter. He also has personal interests in 2D and 3D graphics as well as retro computing and gaming. You can follow him on twitter here. Andy is a DZone MVB and is not an employee of DZone and has posted 9 posts at DZone. View Full User Profile

Comparing JSF Beans, CDI Beans and EJBs

02.14.2012
| 11510 views |
  • submit to reddit

There’s still a lot of confusion over the difference types of managed beans provided in Java EE 6 with EJBs, CDI beans and JSF managed beans all being available. This article aims to clear up some of the differences between the them and define when to use them.

A number of people assume that there is some meaning to all these different types of beans that they just don’t understand. However, the problem is down to the different APIs overlapping which is unfortunate.

JSF Managed Beans, CDI Beans and EJBs

JSF was initially developed with its own managed bean and dependency injection mechanism which was enhanced for JSF 2.0 to include annotation based beans. When CDI was released with Java EE 6, it was regarded as the managed bean framework for that platform and of course, EJBs outdated them all having been around for well over a decade.

The problem of course is knowing which one to use and when, but they all involve the same process. Typically a class has to be identified as a managed bean, and where necessary, will need a scope,qualifiers and a name if it is to be used in JSF. What follows is a brief description of the different types of managed beans and how and when to use them.

Let’s start with the simplest, JSF Managed beans.

JSF Managed Beans

In short, don’t use them if you are developing for Java EE 6 and using CDI. They provide a simple mechanism for dependency injection and defining backing beans for web pages, but they are far less powerful than CDI beans.

They can be defined using the @javax.faces.bean.ManagedBean annotation which takes an optional name parameter. This name can be used to reference the bean from JSF pages.

Scope can be applied to the bean using one of the different scopes defined in the javax.faces.bean package which include the request, session, applicaion, view and custom scopes.

@ManagedBean(name="someBean")
@RequestScoped
public class SomeBean {
    ....
    ....
}

JSF beans cannot be mixed with other kinds of beans without some kind of manual coding.

CDI Beans

CDI is the bean management and dependency injection framework that was released as part of Java EE 6 and it includes a complete, comprehensive managed bean facility. CDI beans are far more advanced and flexible than simple JSF managed beans. They can make use of interceptors, conversation scope, Events, type safe injection, decorators, stereotypes and producer methods.

To deploy CDI beans, you must place a file called beans.xml in a META-INF folder on the classpath. Once you do this, then every bean in the package becomes a CDI bean. There are a lot of features in CDI, too many to cover here, but as a quick reference for JSF-like features, you can define the scope of the CDI bean using one of the scopes defined in the javax.enterprise.context package (namely, request, conversation, session and application scopes). If you want to use the CDI bean from a JSF page, you can give it a name using the javax.inject.Named annotation. To inject a bean into another bean, you annotate the field with javax.inject.Inject annotation.

@Named("someBean")
@RequestScoped
public class SomeBean {

    @Inject
    private SomeService someService;
}

Automatic injection like that defined above can be controlled through the use of Qualifiers that can help match the specific class that you want injected. If you have multiple payment types, you might add a qualifier for whether it is asynchronous or not. While you can use the @Named annotation as a qualifier, you shouldn’t as it is provided for exposing the beans in EL.

CDI handles the injection of beans with mismatched scopes through the use of proxies. Because of this you can inject a request scoped bean into a session scoped bean and the reference will still be valid on each request because for each request, the proxy re-connects to a live instance of the request scoped bean.

CDI also has support for interceptors, events, the new conversation scope and many other features which makes it a much better choice over JSF managed beans.

EJB

EJBs predate CDI beans and are in someways similar to CDI beans and in other ways very different. Primarily, the differences between CDI beans and EJBs is that EJBs are :

  • Transactional
  • Remote or local
  • Able to passivate stateful beans freeing up resources
  • Able to make use of timers
  • Can be asynchronous

The two types of EJBs are called stateless and stateful. Stateless EJBs can be thought of as thread safe single-use beans that don’t maintain any state between two web requests. Stateful EJBs do hold state and can be created and sit around for as long as they are needed until they are disposed of.

Defining an EJB is simple, you just add either a javax.ejb.Stateless or javax.ejb.Stateful annotation to the class.

@Stateless
public class BookingService {

  public String makeReservation(Item Item,Customer customer) {
    ...
    ...
  }
}

Stateless beans must have a dependent scope while a stateful session bean can have any scope. By default they are transactional, but you can use the transaction attribute annotation.

While EJBs and CDI beans are very different in terms of feaures, writing the code to integrate them is very similar since CDI beans can be injected into EJBs and EJBs can be injected into CDI beans. There is no need to make any distinction when injecting one into the other. Again, the different scopes are handled by CDI through the use of proxying. One exception to this is that CDI does not support the injection of remote EJBs but that can be implemented by writing a simple producer method for it.

The javax.inject.Named annotation as well as any Qualifiers can be used on an EJB to match it to an injection point.

When to use which bean

How do you know when to use which bean? Simple.

Never use JSF managed beans unless you are working in a servlet container and don’t want to try and get CDI working in Tomcat (although I have a Maven archetype for that so there’s no excuse).

In general, you should use CDI beans unless you need the advanced functionality available in the EJBs such as transactional functions. You can write your own interceptor to make CDI beans transactional, but for now, its simpler to use an EJB until CDI gets transactional CDI beans which is just around the corner. If you are stuck in a servlet container and are using CDI, then either hand written transactions or your own transaction interceptor is the only option without EJBs.

 

From http://www.andygibson.net/blog/article/comparing-jsf-beans-cdi-beans-and-ejbs/

Published at DZone with permission of Andy Gibson, author and DZone MVB.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Goel Yatendra replied on Thu, 2012/03/15 - 4:06pm

Hi Andy, Very nice article.
By the way using using extension libraries like seam3, DeltaSpike (currently under heavy development) or myfaces codi is recommended because they will add some nice features and utilities and integration with other technologies like Logging, Exception handling, security, etc.
And if you are limited to servlet container and are not able to use EJBs seam3 can help you to make transactional beans and methods using @Transactional annotations.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.