Is @javax.faces.bean.ManagedBean Dead on Arrival?

Java EE 6 has three different ways of defining “beans” that are “managed” in one way or another. Here is a quick recap.

JSR 314

JSF 2.0 introduced annotations to avoid the tedium of declaring managed beans in faces-config.xml:

public class UserBean implements Serializable {

That's certainly nicer than


There is a second annotation for a rudimentary dependency injection mechanism:

public class EditBean {
   private UserBean currentUser;

When an EditBean instance is constructed, the value expression #{user} is evaluated, and the result is passed to the setCurrentUser method (which you must also supply)

(It is a bit odd that the @ManagedProperty annotation is applied to a field when in fact the property setter is invoked. That is not how injection works elsewhere in Java EE. Let's not dwell on this oddity.)

JSR 316

There is an annotation @javax.annotation.ManagedBean, defined by JSR 316, that attempts to generalize JSF managed beans for use elsewhere in Java EE. There isn't much there. You can use the @PostConstruct and @PreDestroy annotations. You can use @Resource for injecting EE resources. You can use interceptors. For example, if you define

@javax.annotation.ManagedBean("user") public class UserBean ...

then you can construct an instance by making a JNDI lookup for java:module/user. But there is no interaction with an expression language, and there is no notion of scopes. So, perhaps this kind of managed bean isn't going to see a lot of love.

JSR 299

In an EE 6 container, you can use JSR 299 “contexts and dependency injection” (CDI), like this:

public class UserBean implements Serializable {

Now you refer to the bean as #{user} in JSF, just like you would with JSF managed beans.

If you try this out, remember to put an empty beans.xml into web/WEB-INF to trigger the CDI implementation. This works today with GlassFish v3.

What is the advantage? Well, first off, @Named("user") is shorter than @ManagedBean(name="user"), so you are doing your part alleviating the global pixel shortage.

The advocates of CDI will tell you that they offer facilities for managing beans that go far beyond what JSF has to offer, and that is certainly true. For example, injection works with types, not EL expressions. You would use

@Inject private UserBean currentUser;

Then the CDI implementation automatically injects the UserBean of the appropriate scope. You use annotations (which you define) to control this process, such as

@Inject @LoggedIn private UserBean currentUser;

I won't go into detail here. See the documentation of Weld, the CDI reference implementation, which is very well written. For a quick intro, check out this blog by Roger Kitain.

Dependency injection is all good and well, but here is a more immediate “selling point” for a JSF programmer. CDI supports the usual request, session, and application scope, but it also provides a conversation scope, a scope whose lifetime is controlled by the application. That's a sorely needed feature to deal with two separate problems: session bloat and multiple browser windows. Again, the Weld documentation describes this quite nicely.

Now What?

So, should we ditch @javax.faces.bean.ManagedBean before too many people get used to it? If you deploy in an EE 6 container, then there is really no reason to use @ManagedBean. Just use @Named and start using CDI—it's there, so why not take advantage of it? If you use Tomcat or another servlet runner, you can also get CDI by adding the Weld implementation to your web app. According to a recent conversation on the jsr-314-open mailing list (which, sadly, doesn't seem to be archived), Spring 3.0 supports @Named as well, so that seems to be the way to go for consistent examples.

On the flip side, IDE support isn't quite there yet (see this bug—please vote for it), and there will always be some people who will want to use Tomcat without any additional libraries.

Why do I care? We have a very short window for replacing all @ManagedBean with @Named before the 3rd edition of Core JSF goes to print, and I wonder whether we should do it. Please comment! (But please, no flame wars on JSF or CDI—there is a better forum for those :-))