What' the purpose of @Named annotation
Asked Answered
S

4

5

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>

~

Salcido answered 27/9, 2014 at 5:57 Comment(0)
P
5

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

Pinfish answered 27/9, 2014 at 7:6 Comment(5)
What's the exact reason for the fact that once @Singleton is removed, the counter doesn't work? Counter's values stay at 1, doesn't increment.Salcido
I think it's not that the value stays the same but that you get a new instance every time you access your webapp. Unfortunately I can't see in what context the class is used.Pinfish
please see how it's used. Very simple. It is a simple demo demonstrating the concept of singleton session bean. You mean everytime I click "Increment", I got a new instance? But default value is 1, even if I click only once, a new instance should get a value of 2?Salcido
On the same page, same browser session, I click the same button "Increment". The value may or may not change, depending on whether @Singleton is added to the class.Salcido
Isn't @Named a singleton by default? Why would you need both? docs.spring.io/spring/docs/current/spring-framework-reference/…Mirabelle
S
2

The singleton annotation make an EJB unique in an entire EE application (look shared between threads and requests), is pretty different from other types of EJB like Session Beans, that have a life in a Session and in that session maintain the internal state. Be careful: singletons can impact on performance when used in high concurrency environments.

What about @Named, i don't work on Java EE7 but i think is more used in JSF to give a different name to what was known as ManagedBean (managed beans are deprecated in new version of Java EE). Simply if you make a bean named MyBean the you can refer to that bean as myBean in JSF pages, if you want to use a different name you can use:

@Named("myNewBeanName")

and you can use the myNewBeanName in JSF pages.

Schmuck answered 27/9, 2014 at 6:56 Comment(6)
Please see the edited details. I am the same client, in the same browser seesion, and I continuously click "Increment". Each click represents one unique session that's changing for each click, or all clicks represent one common session that's shared? My understanding is that it's all one session, since I am on the same page and didn't open a new web page, or new tab.Salcido
Without @Singleton, does it become a stateless bean? Does stateless beans have to be explictily annotated with "stateless"?Salcido
Without @Singleton it's no longer an EJB at all, it's a plain CDI managed bean now.Pinfish
Regarding the counting the scope used for counter is the default ,(at)Dependent, so that a new instance is used for every invocation of the page. Please see docs.jboss.org/cdi/api/1.0/javax/enterprise/context/… : If you add (at)SessionScoped to your class the counter should count per session.Pinfish
Hi, from the Oracle J7EE Tutorial:The Hello class, called a managed bean class, provides getter and setter methods for the name property used in the Facelets page expressions. By default, the expression language refers to the class name, with the first letter in lowercase [...] If you use the default name for the bean class, you can specify Model as the annotation instead of having to specify both Named and RequestScoped. The Model annotation is called a stereotype, a term for an annotation that encapsulates other annotations. So if you don't use Singleton the Bean will not be an EJB.Schmuck
A singleton is shared between al clients in the entire application, even if a client terminate his session a then starts a new one. Try to deploy the application with the Singleton annotation and then start more browsers and click the link, you will notice that the value will be maintained.Schmuck
P
2

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.

Penniepenniless answered 27/9, 2014 at 19:11 Comment(0)
N
1

If you have different beans implementing the same interface and you want to pick one based on deployment configuration (e.g. a SELECTED_IMPLEMENTATION env var), you can use @Name("MyImplementation") to name differently each one of them, then select the configured one on injection like:

@Inject
@ConfigProperty(name = "SELECTED_IMPLEMENTATION", defaultValue = "MyImplementation")
String selectedImplementation;

@Inject @Any Instance<MyInterface> implementations;
...
implementations.select(new NamedQualifier(selectedImplementation));

You can put that on a producer (E.g. the @Default one).

(Perhaps there is a better way to do this, like the profiles you find on Spring, but this is the best one I know of using only CDI and eclipse microprofile configuration)

Niehaus answered 26/9 at 8:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.