In Java EE 7, what's the purpose and use of @Named annotation here? Even without it, the container should be able to discover this bean at runtime, right?
Also, what about the @Singleton do? If developers don't need to create multiple instances in application, there is no need to use singleton here, right?
@Singleton
@Named
public class Counter {
private int a = 1;
private int b = 1;
public void incrementA() {
a++;
}
public void incrementB() {
b++;
}
public int getA() {
return a;
}
public int getB() {
return b;
}
}
I did two tests:
1) If i remove the @Singleton, when I click the incrementA() or incrementB(), neighter increments by 1. The value stays at 1.
2) If I remove the @Named annotation, it reports a null pointer exception.
I am learning Java EE and not quite understand this behavior.
EDIT (how the bean is used):
<html lang="en" xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets">
<body>
<ui:composition template="/template.xhtml">
<ui:define name="title">
Helloworld EJB 3.1 Singleton Quickstart
</ui:define>
<ui:define name="body">
<p>
This example demonstrates a singleton session bean that maintains state for 2 variables: <code>a</code> and <code>b</code>.
</p>
<p>
A counter is incremented when you click on the
link to the variable name. If you close and restart your browser, or
if you have multiple browsers, you can see that the counter always
increments the last value. These values are maintained until you
restart the application. To test the singleton bean, click on either
"Increment" button below.
</p>
<table>
<tr>
<h:form>
<td><b>Counter A</b></td><td><h:commandButton value="Increment" action="#{counter.incrementA}" /></td><td>#{counter.a}</td>
</h:form>
</tr>
<tr>
<h:form>
<td><b>Counter B</b></td><td><h:commandButton value="Increment" action="#{counter.incrementB}" /></td><td>#{counter.b}</td>
</h:form>
</tr>
</table>
</ui:define>
</ui:composition>
~
Without @Named the Bean will not be available for use in an EL in JSF.
Without @Singleton the bean is a plain CDI ManagedBean. Instead of having exactly one singleton instance that counts there is one Managed Bean per scope. When you remove @Singleton it's probably best to add @SessionScoped or @ApplicationScoped depending on whether you want to count per session or over all sessions (like it does with @Singleton).
With CDI, you need a pair of scope and qualifier(s) for your beans. Singleton is your example of scope, and Named is your example of a qualifier. The Qualifier is how the bean can be derived when being looked up. Named is specifically used when combined in a presentation layer to refer to it in a view or similar. Singleton allows it to be exposed as a single instance. Note that Singleton is from the AtInject spec, and is not considered bean defining, it's not a normal scope. The more CDI centric way to do this is to use ApplicationScoped. Either way, a single instance of your class will be created.
Qualifiers are optional, so you only need Named if you want to make it available in the UI.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With