Are #ManagedBeans obsolete in JavaEE6 because of #Named in CDI/Weld? - jsf

Because of CDI (and its implementation Weld), every POJO in JEE6 can be annotated with #Named, which makes the POJO accessible to the view.
Does that mean that ManagedBeans are completely obsolete now?
Or did I miss something where #ManagedBean still makes sense?

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.

You have a choice. Either use the #ManagedBean from JSF2 to bind beans into your forms, or use the #Named annotation from CDI. If you plan on only doing JSF, you can stick to #ManagedBean, but if you want to integrate with EJB's, or make use of CDI's #ConversationScoped, then go the CDI route.
Personally I feel the next version of JSF should deprecate the #ManagedBean, and standardize on CDI. The duality is confusing to newcomers.

CDI has no view scope, because it doesn't have the notion of a view, so if you need that scope, CDI in its pure form can't do it. View scope basically means request scope + being AJAX-ready. It's not a JSF view, like a page named xyz.xhtml, even though you see JSF <f:viewParam> and the likes. A frequent use case with view-scoped beans is how to get GET parameters into a such a bean. Also read this.
Note that CDI rather lives at the EJB/service layer than the JSF/presentation layer. This blog has a nice overview.
As such #ManagedBean cannot be fully replaced by CDI, again if you're using #ViewScoped beans - at least not without extending CDI or using the Seam 3 Faces module. Using view-scoped beans is almost always going to happen when using AJAXed JSF 2-based GUI toolkits like RichFaces, PrimeFaces, IceFaces etc.
Mixing annotations from the wrong Java EE 6 packages can get you in trouble unexpectedly, again when using RichFaces or a similar API:
#javax.faces.bean.ManagedBean
#javax.faces.bean.[Jsf]Scoped
are for components used solely at the presentation layer, here by RichFaces, PrimeFaces, etc. Some rich components seem to have problems with CDI-annotated and JSF-annotated helper beans. If you get strange behavior from your beans (or beans that seem to do nothing) the wrong mix of annotations might be the cause.
Mixing JSF and CDI, like
#javax.inject.Named
#javax.faces.bean.[Jsf]Scoped
is possible and works in most cases when referenced from JSF pages, however there are some little-known issues/drawbacks, e.g. when using a JSF scope which CDI doesn't have:
Also the combination #Named #ViewScoped won't work as intended. The JSF-specific #ViewScoped works in combination with JSF-specific #ManagedBean only. Your CDI-specific #Named will behave like #RequestScoped this way. Either use #ManagedBean instead of #Named or use CDI-specific #ConversationScoped instead of #ViewScoped.
Then
#javax.inject.Named
#javax.faces.bean.[Cdi]Scoped
can be used for CDI beans directly referenced from your JSF pages AFAIK. I haven't had any problems with the above combinations so far, so you could consider #ManagedBean obsolete here.
What's left is the service layer, here mostly transactional EJB service beans declared as
#javax.ejb.*
mostly #javax.ejb.Stateless. You can even annotate and use EJBs directly from JSF pages - though I'm not sure if this design is desirable. To reference (inject) any components annotated with #javax.ejb.*, e.g. #Stateless, prefer #Inject over #EJB as described here. (Probably an ancestor of this answer...)
Finally, a very nice overview of Java EE 6 annotations can be found here:
http://www.physics.usyd.edu.au/~rennie/javaEEReferenceSheet.html
Note: the above info is not from an expert, but simply my own take/sight from a newcomers perspective on this ridiculously confusing Java EE 6 annotations spaghetti. More insight has yet to be developed. I hope this answer can endure to be a general, practical answer to this confusion - even though it has gone a little overboard in the context of the original question.

As i Just read in the Weld Reference (p. 12), #ManagedBean is now superflous:
You can explicitly declare a managed
bean by annotating the bean class
#ManagedBean, but in CDI you don't
need to. According to the
specification, the CDI container
treats any class that satisfies the
following conditions as a managed
bean:
It is not a non-static inner class. It is a concrete class, or is
annotated #Decorator.
It is not annotated with an EJB component-defining annotation or
declared as an EJB bean class in
ejb-jar.xml.
It does not implement javax.enterprise.inject.spi.Extension.
It has an appropriate constructor—either:
the class has a constructor with no parameters, or
the class declares a constructor annotated #Inject.

Related

Injecting commonly used CDI beans in abstract parent class

This is more of a good practice question...
We're converting JSF managed beans to CDI beans in JSF 2.2 . While doing this, it seems in a LOT of beans, we need a few sessionscoped beans.
We initially intended to #Inject those, but another option would be to inject them into a protected variable in a parent "FacesBean" class.
Would this be good practice?
Does #Inject also work in #ManagedBean classes that were not yet converted to CDI?
So one by one:
1) Good practice?
If you have a class hierarchy, I suggest you #Inject it into a private field in the parent and then create a getter method with minimum needed visibility (probably protected). Just stick to general good practice rules around encapsulation in Java.
2) #ManagedBean and #Inject?
As long as you use bean discovery mode all (use empty beans.xml), your classes will be automatically picked up as managed beans - including those annotated with #ManagedBean. And as soon as it is a bean, injection works. So yes, injection will work as long as the class can become a bean automatically (e.g. it is not #Vetoed or unproxyable etc.)

Split CDI bean in windowscope for separation of concerns

I have a JSF application with RichFaces 4.5.8, deltaspike for CDI beans, and EJBs which runs in an EAP 6.3. I have a page with two tables and several popupPanels. The page is backed by a CDI bean controller in WindowScope. By now the page becomes larger and larger, because the popupPanels have a lot of controls and actions.
The xhtml page is separated by composite components and ui:include's which works fine, but the CDI bean becomes larger an larger. I would like to move the action methods of the popupPanels into other CDI beans, but for me it sounds strange to have several windowScoped CDI beans in one page.
What would you do to split up the large CDI bean?
Best regards
#DarWhi's comment is correct - you may use as many WindosScoped beans in your page as you want, all of them will live only with one window. There is no restriction that you must use only single bean in the JSF page. You just need to give a name using #Named to all of such beans.
If you prefer to have only one WindowScoped bean per window, you may still separate your logic into multiple beans,. Just inject all child beans into the WindowScoped bean, and then reference actions in child beans using dot notation: #{viewScopedBean.childBean.action.
You may use variables to store references to childBeans and make your code in JSF shorter, see this answer.

Can I put #ManagedBean in CDI scope?

I'm using GlassFish 3.0.1. I want to know if I can use:
#ManagedBean
#ConversationScoped
Instead of #Named?
#ManagedBean is a JSF annotation while #ConversationScoped is a CDI annotation, I can't think of any valid scenario to combine them.
In general #Named will cover almost all you needs and it make your bean available to EL thus the JSF pages.

JSF Managed bean and managed property both necessary?

I'm new to JSF and was wondering:
If I have a controller that handles all the work for a given page and a bean that holds all the data for said page, is It necessary to have both the
#ManagedProperty(value="#{myBean}")
annotation on the controller and the
#ManagedBean(name="myBean")
#SessionScoped
annotations on the form bean?
Managed beans in JSF are used to store the state of a web page. The JSF implementation is responsible for creating and discarding the bean objects( hence the name managed bean).
For every class you write #ManagedBean, the bean object is created by the JSF implementation as and when it detects an usage of the bean with the name(you can either sepcify a bean name or leave it to JSF to use the default name-class name with the first character changed to lowercase). The object created is placed in a map of the specified scope. Each scope has a map that it uses to store bean objects which have that scope specified.
Now if you need the values of these beans in your controller, you have to inject it using the ManagedProperty annotation. Note that you would need to provide the controller with a setter method for the managedProperty.
So to answer your question, the managedBean annotation is required to tell the JSF implementation to manage the bean instance and store the values in the table specific to the session scope. And the ManagedProperty annotation is needed to use that bean stored in the current session so that you can access all of its values.
We use #ManagedBean annotation to register a java bean with a JSF framework. This is a replacement for a faces-config.xml <managed-bean> element. We typically do not use name attribute because it already defaults to a simple class name camel cased.
We use #RequestScope and other scope annotations to explicitly specify the scope we want via annotation. This is equivalent to specifying<managed-bean-scope> xml entry. If you don't specify the scope it will be defaulted to #NoneScoped.
We use #ManagedProperty and specify an EL-expression in its value attribute to use JSF-provided dependency injection engine for JSF artifacts like other managed beans with broader scopes and EL-defined variables like param. We do it in case we need the injected values in other JSF artifacts, most typically beans. The injected values are available in bean's #PostConstruct-annotated method. This is an alternative to <managed-property> xml entry.
To sum it up. Use #ManagedBean #RequestScoped to register a bean with JSF framework. Use #ManagedProperty inside this bean to be able to reference among others other JSF beans with the same or broader scopes in this bean. In case you don't need to reference other beans in the created bean you don't need to use the #ManagedProperty annotation as it's purely optional.

Java EE 6 and CDI

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
#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.)

Resources