Java Ee 6 @Javax.Annotation.Managedbean VS. @Javax.Inject.Named VS. @Javax.Faces.Managedbean

Java EE 6 @javax.annotation.ManagedBean vs. @javax.inject.Named vs. @javax.faces.ManagedBean

First of all let me do some clarifications:

Managed bean definition : generally a managed bean is an object that its life cycle (construction, destruction, etc) is managed by a container.

In Java ee we have many containers that manage life cycle of their objects, like JSF container, EJB container, CDI container, Servlet container, etc.

All of these containers work kind of independent, they boot in application server initialization and scan classes of all artifacts including jar, ejb-jar, war and ear files in deployment time and gather and store some metadata about them, then when you need an object of a class at runtime they will give you instances of those classes and after finishing the job, they will destroy them.

So we can say that we have:

  • JSF managed beans
  • CDI managed beans
  • EJB managed beans
  • And even Servlets are managed beans because they are instantiated and destroyed by a container, which is a servlet container.

So when you see the Managed Bean word, you should ask about the context or type of it.(JSF, CDI, EJB, etc.)

Then you might ask why we have many of these containers: AFAIK, Java EE guys wanted to have a dependency injection framework, but they could not gather all requirements in one specification because they could not predict the future requirements and they made EJB 1.0 and then 2.0 and then 3.0 and now 3.1 but EJB's target was for just some requirements (transaction, distributed component model, etc).

At the same time (in parallel) they realized that they need to support JSF too, then they made JSF managed beans and another container for JSF beans and they considered it a mature DI container, but still it was not complete and mature container.

After that Gavin King and some other nice guys ;) made CDI which is the most mature DI container I've seen. CDI (inspired by Seam2, Guice and Spring) was made to fill the gap between JSF and EJB and lots of other useful stuff like pojo injection, producer methods, interceptors, decorators, integration SPI, very flexible, etc. and it can even do what EJB and JSF managed beans are doing then we can have just one mature and powerful DI container. But for some backward compatibility and political reasons Java EE guys want to keep them!!!

Here you can find the difference and use cases for each of these types:

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 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, application, 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 features, 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 there are some Maven archetypes 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, it's 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.

If you need to use @ViewScoped in CDI you should

  • use seam-faces or MyFaces CODI module. just add one of them to your classpath and @ViewScoped will work in CDI. MyFaces CODI has an even more solid support of @ViewScoped
  • use MyFaces CODI's @ViewAccessScoped, it is an extension written on top of CDI by Apache, just download it and use @ViewAccessScoped annotation instead of @ViewScoped.
  • Use CDI @ConversationScoped and make it long running. See here for more info.
  • Use Omnifaces @ViewScoped annotation

Some parts pilfered from here.

Why are there different bean management annotations

  1. javax.enterprise.context.SessionScoped(JSR 346) and all other annotations under the javax.enterprise.context.* package maintain the context of CDI. CDI provides an alternative, versatile and more powerful mechanism for dependency injection, bean and general resource management within the Java EE space. It's an alternative to JSF managed beans and it's set to even supersede the JSF bean management mechanism in the coming version of JSF.

    Currently, JSF and CDI annotated beans are interchangeable within any given Java EE web application (given a handful of minor restrictions). CDI annotated beans however, extend far beyond the realm of the web tier, which is why the Java EE spec is evolving to make CDI the standard bean and DI mechanism.

    While CDI might be an obvious choice for all Java EE development, JSF managed beans are portable across servlet containers (Tomcat) and application servers (Glassfish, JBoss, etc.). CDI beans can live within only full application servers. With some legwork however, Tomcat 7 can be wired to support CDI.

    Specifically, javax.enterprise.context.SessionScoped is the parallel implementation of the JSF Session Scope within CDI.

  2. javax.faces.bean.SessionScoped (JSR 314) and all other annotations under the javax.faces.bean.* package maintain the JSF-specific dependency injection and bean management mechanism. Beans annotated with JSF annotations however are only useful within the web tier. All the scopes available with JSF annotations have been replicated within the CDI specification.

  3. javax.annotation.ManagedBean (JSR 316) and other DI-related annotations under javax.annotation.* are an attempt to generalize the JSF-based annotations for other uses within the Java EE spec and really shouldn't be used by the end-developer.

Why they exist? Well IMO, the move from JSF beans to CDI beans is a natural evolution of the technology. JSF beans have had a good run but the likes of Spring, Guice and Seam made it obvious that the technology was not sufficient. There was also a need to bridge the gap between the web components and EJBs, and the response to that need is CDI.

See these related questions too:

  • JSF: Backing beans (@ManagedBean) or CDI Beans (@Named)?
  • Java EE 6 @javax.annotation.ManagedBean vs. @javax.inject.Named vs. @javax.faces.ManagedBean

Why are there different bean management annotations

  1. javax.enterprise.context.SessionScoped(JSR 346) and all other annotations under the javax.enterprise.context.* package maintain the context of CDI. CDI provides an alternative, versatile and more powerful mechanism for dependency injection, bean and general resource management within the Java EE space. It's an alternative to JSF managed beans and it's set to even supersede the JSF bean management mechanism in the coming version of JSF.

    Currently, JSF and CDI annotated beans are interchangeable within any given Java EE web application (given a handful of minor restrictions). CDI annotated beans however, extend far beyond the realm of the web tier, which is why the Java EE spec is evolving to make CDI the standard bean and DI mechanism.

    While CDI might be an obvious choice for all Java EE development, JSF managed beans are portable across servlet containers (Tomcat) and application servers (Glassfish, JBoss, etc.). CDI beans can live within only full application servers. With some legwork however, Tomcat 7 can be wired to support CDI.

    Specifically, javax.enterprise.context.SessionScoped is the parallel implementation of the JSF Session Scope within CDI.

  2. javax.faces.bean.SessionScoped (JSR 314) and all other annotations under the javax.faces.bean.* package maintain the JSF-specific dependency injection and bean management mechanism. Beans annotated with JSF annotations however are only useful within the web tier. All the scopes available with JSF annotations have been replicated within the CDI specification.

  3. javax.annotation.ManagedBean (JSR 316) and other DI-related annotations under javax.annotation.* are an attempt to generalize the JSF-based annotations for other uses within the Java EE spec and really shouldn't be used by the end-developer.

Why they exist? Well IMO, the move from JSF beans to CDI beans is a natural evolution of the technology. JSF beans have had a good run but the likes of Spring, Guice and Seam made it obvious that the technology was not sufficient. There was also a need to bridge the gap between the web components and EJBs, and the response to that need is CDI.

See these related questions too:

  • JSF: Backing beans (@ManagedBean) or CDI Beans (@Named)?
  • Java EE 6 @javax.annotation.ManagedBean vs. @javax.inject.Named vs. @javax.faces.ManagedBean

ejb - Details requried on javax.annotation.ManagedBean

  1. Neither. They are per lookup/injection instances, more like stateful.

  2. No, there is no container-managed concurrency.

  3. (and 4.) Do you need transaction, security, or other EJB capabilities? Then @Stateless is probably better. Otherwise, I would just use CDI since it is better than the @javax.annotation.ManagedBean annotation in nearly all ways, and it is enabled by default in EE 7, so it is clearly the forward direction for EE.

As a bit of background, the @javax.annotation.ManagedBean annotation was added late in the development of the EE 6 cycle, and it is not widely used. The managed bean spec was intended to unify the lifecycle, injection, and naming behaviors of the EJB, CDI, and JSF managed bean component models. That was useful, but in my opinion, the @javax.annotation.ManagedBean annotation was just an afterthought to allow developers to access the minimal component model functionality without the overhead/complexity (real or perceived) of the other component models (EJB necessarily has a fixed set of required services and associated overhead, CDI is better in nearly all ways but is clearly more complex, and JSF managed beans are tied to WAR). However, this "common denominator" is then a quite limited component model with just @PostConstruct, @Resource (and other EE injection), and @Interceptors. There's no security, transaction, scoping/lifecycle (as in EJB or CDI), @PreDestroy, tight integration with the web tier, etc.

Issues with usage of CDI v/s JSF annotations

If someone want to understand the full blown concept and reasons around this issue then refer this answer which was recommended by @Kukeltje, thanks mate.

Below is the short summary of my issue and what I have learned from this:

  • Root cause of my issue was that even though I was using javax.inject.Named annotation but it was not taking effect because I was not creating the CDI container.
  • Code fix was to include the beans.xml file in WEB-INF directory. Read this on how to configure a CDI application. So, basically what I was missing was I didn't configure the CDI, so that annotation was not taking effect.

    • On a side note, since mine was JEE 6 container so I explicitly needed beans.xml file, in JEE 7 container if any class has CDI annotations then server will automatically recognize the application as CDI application, read more here.
  • One other important thing I learned is that CDI annotations are preferred over JSF annotations (good that I identified and came across this issue otherwise I might have ended up using JSF annotations).

What makes a bean a CDI bean?

By CDI specification, every JavaBean is a Managed Bean (do not confuse it with JSF @ManagedBean, this is a different one) in project where the beans.xml is present. So every class is also eligible for dependency injection. Note that default scope of this class is Dependent.

After switching @ManagedBean to @Named: javax.el.PropertyNotFoundException: Target Unreachable, identifier 'person' resolved to null

This is the best answer to my problem LINK
. Also, cdi-1.2 jar file is not available in GS 4.1 for some reason, that is why the package javax.enterprise.* was not present in my Netbeans, I had to manually download that jar from http://cdi-spec.org/. Now everything works fine including DI. And I did not have to create any configuration files to get it to work either.

Are @ManagedBeans obsolete in JavaEE6 because of @Named in CDI/Weld?

In short, @ManagedBean makes sense for applications that use JSF but do not use JSR 299 (whatever the reason is). Below a longer explanation from Gavin King:

Re: Comparisons to @ManagedBean annotations in JSF2?:


While looking through the Weld examples, and the older WebBeans
documentation, it looks like a
competitor to the new @ManagedBean JSF
2.0 annotations. Is there any information on when we'd want to use
one over the other?


It's a good question, and I'm not
really in full agreement with the
answers that have been posted so far.

The new EE Managed Beans specification
defines a base component model for
Java EE, together with a very basic
set of container services (@Resource,
@PostConstruct, @PreDestroy).

The idea is that other specifications
(beginning with EJB, CDI, JSF and the
new Java Interceptors spec) build upon
this base component model and layer
additional services, for example
transaction management, typesafe
dependency injection, interceptors. So
at this level, the managed beans, CDI,
interceptors and EJB specifications
all work hand-in-hand and are highly
complementary.

Now, the Managed Beans specification
is quite open-ended with respect to
identifying exactly which classes are
managed beans. It does provide the
@ManagedBean annotation as one
mechanism, but it also allows other
specifications to define different
mechanisms. So, for example:

  • The EJB specification says that a class obeying certain programming
    restrictions with a @Stateless or
    @Stateful annotation deployed in an
    EJB jar is a managed bean.

  • The CDI specification says that any class with an appropriate constructor
    deployed in a "bean deployment
    archive" is a managed bean.


Given that EJB and CDI provide
arguably more convenient ways to
identify a managed bean, you might
wonder precisely what @ManagedBean is
needed for. The answer, as alluded to
by Dan, is that if you have CDI
available in your environment (for
example, if you are using EE6), then
@ManagedBean is just not really
needed. @ManagedBean is really there
for use by people who are using JSF2
without CDI
.

OTOH, if you do annotate a bean
@ManagedBean, and you do have CDI in
your environment, you can still use
CDI to inject stuff into your bean.
It's just that the @ManagedBean
annotation is not required in this
case.

To summarize, if you do have CDI
available to you, it provides a far
superior programming model to the
@ManagedBean/@ManagedProperty model
that JSF2 inherits from JSF1
. So
superior, in fact, that the EE 6 web
profile does not require support for
@ManagedProperty etc. The idea being
that you should just use CDI instead.

Error deploying on Glassfish v.3 after using @SessionScoped

You can't use the CDI annotation javax.enterprise.context.SessionScoped with the JSF javax.faces.bean.ManagedBean. You either go pure JSF with

  • javax.faces.bean.ManagedBean(naming) and javax.faces.bean.SessionScoped (scoping)

    OR Pure CDI

  • javax.inject.Named (naming) and javax.enterprise.context.SessionScoped(scoping)

Related:

  • Java EE 6 @javax.annotation.ManagedBean vs. @javax.inject.Named vs. @javax.faces.ManagedBean


Related Topics



Leave a reply



Submit