What is the correct annotation for a java class to be injectable? - cdi

I have a POJO which I want to inject into a CDI Bean. Now I get that I could change the discovery mode in beans.xml from 'annotated' to 'all'. But I also could just give my POJO a bean defining annotation. I guess any annotation would work, but I was wondering, what is the correct annotation just for the single purpose to make my POJO injectable?

#Dependent will create a new instance for that bean on every injection point. Usually the least intrusive.
http://docs.oracle.com/javaee/7/api/javax/enterprise/context/Dependent.html

Assuming you want to stay with bean discovery mode annotated, you need to have a bean-defining annotation on your POJO which will make it so called implicit bean. Here is a relevant quotation from CDI spec:
The set of bean defining annotations contains:
#ApplicationScoped, #SessionScoped, #ConversationScoped and #RequestScoped annotations,
all other normal scope types,
#Interceptor and #Decorator annotations,
all stereotype annotations (i.e. annotations annotated with #Stereotype),
and the #Dependent scope annotation.
As for which annotation is correct - that depends on your use case. Typically you need to take into consideration the lifecycle of beans (requests, conversations, application scoped which lives as long as the app does). But if you really don't care, I would say just go for #Dependent.
In fact, if you have bean discovery mode all and had no annotation on that POJO class, it would be picked up by CDI as #Dependent anyway.
Hope that answers the question.

You may have no annotation at all, no annotation is required to make your bean injectable (i.e. to make it managed or cdi bean).
In order to inject class it should be:
Concrete class (i.e not abstract or interface) or it should annotated as #Decorator
Should have no-arg constructor or constructor annotated with #Inject
Should not have annotated with an EJB component-defining annotation or declared as an EJB bean class in ejb-jar.xml.
So you can inject, pretty much, all 'normal' classes. Also, the class should be located inside bean archive. Starting from CDI 1.1 there are two types of bean archives: implicit and explicit. From Oracle documentation:
An explicit bean archive is an archive that contains a beans.xml
deployment descriptor, which can be an empty file, contain no version
number, or contain the version number 1.1 with the bean-discovery-mode
attribute set to all. For example:
http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
version="1.1" bean-discovery-mode="all">
... CDI can manage and inject any bean in an explicit archive, except those annotated with #Vetoed.
An implicit bean archive is an archive that contains some beans
annotated with a scope type, contains no beans.xml deployment
descriptor, or contains a beans.xml deployment descriptor with the
bean-discovery-mode attribute set to annotated.
In an implicit archive, CDI can only manage and inject beans annotated
with a scope type.
For a web application, the beans.xml deployment descriptor, if
present, must be in the WEB-INF directory. For EJB modules or JAR
files, the beans.xml deployment descriptor, if present, must be in the
META-INF directory.

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

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.

What is the default Managed Bean Scope in a JSF 2 application?

Normally the default scope is the Request scope. I ve tried to delete the scope annotation and expected the bean to have a request bean scopped behaviour (by returning a submitted value on a previous page, I remember i've tried this the past and it worked fine) but i got nothing on the expression language wired to it.
So what is the default scope and why it's not the same behaviour?!
Depends on who's managing the bean.
If it's JSF via #ManagedBean, then it defaults to #RequestScoped, as mentioned in the javadoc:
If the scope annotations are omitted, the bean must be handled as if the RequestScoped annotation is present
If it's CDI via #Named, then it defaults to #Dependent, as mentioned in Weld documentation:
Finally, CDI features the so-called dependent pseudo-scope. This is the default scope for a bean which does not explicitly declare a scope type.
The effect is that the bean instance is newly created on every single EL expression. So, imagine a login form with two input fields referring a bean property and a command button referring a bean action, thus with in total three EL expressions, then effectively three instances will be created. One with the username set, one with the password set and one on which the action is invoked. In effects, this behaves the same as JSF #NoneScoped. This confirms the symptoms you're seeing.
If it's Spring via #Component, then it defaults to #Scope("singleton"), as mentioned in javadoc:
Default: "singleton"
In effects, this behaves the same as JSF #ApplicationScoped and CDI #ApplicationScoped.
Netbeans has got nothing to do with it. It's just an editing tool like notepad but then with 1000+ extra features.
See also:
what is none scope bean and when to use it?
How to choose the right bean scope?

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

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

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.

Resources