147

I am trying to understand the javax.inject package and I am not clear what the javax.inject.Named annotation is supposed to be used for. The Javadoc does not explain the the idea behind it.

Javadoc is at http://download.oracle.com/javaee/6/api/javax/inject/Named.html

I am using Spring 3.0 to write some sample programs, by putting @Named on a bean it seems to add it to the bean factory but the Javadoc description is so light I can't tell if that is the standard behavior or Spring specific behavior.

My questions are:

  1. What is the difference between @Named and @Qualifier
  2. How are you supposed to tell the Runtime system a class should be injectable in other classes what's the annotation for that? The equivalent of @Component in Spring?

Update 1 there is an excellent explanation of @Named and @Qualifier at Nice article about @Named and @Qualifier https://dzone.com/articles/java-ee6-cdi-named-components thanks @xmedeko for linking to it the comment below.

JL_SO
  • 1,742
  • 1
  • 25
  • 38
ams
  • 60,316
  • 68
  • 200
  • 288
  • The configuration of JSR-330 is outside the spec, i.e. container specific. – Thorbjørn Ravn Andersen Mar 24 '11 at 07:13
  • 1
    According to the Spring docs "JSR 330's @Named annotation can be used as a means to both detect components and to provide them with a name. This behavior is enabled automatically if you have the JSR 330 JAR on the classpath." is this behavior unique to spring or to all containers that understand @Named? – ams Mar 24 '11 at 08:24

4 Answers4

109

Use @Named to differentiate between different objects of the same type bound in the same scope.

@Named("maxWaitTime")
public long maxWaitTimeMs;

@Named("minWaitTime")
public long minWaitTimeMs;

Without the @Named qualifier, the injector would not know which long to bind to which variable.

  • If you want to create annotations that act like @Named, use the @Qualifier annotation when creating them.

  • If you look at @Named, it is itself annotated with @Qualifier.

CodeSlave
  • 425
  • 6
  • 21
sbridges
  • 24,960
  • 4
  • 64
  • 71
  • So @Named really is @Qualifier, so why is @Qualifier required to be so generic, is the idea to allow someone using javax.inject to define stereotypes like @Repository,@Service,@Controller that are marked up as @Qualifier? – ams Mar 24 '11 at 06:09
  • I'm not sure what you mean about stereotypes. If you mean adding new annotations to distinguishing between different instances of the same Type, then yes. – sbridges Mar 24 '11 at 12:49
  • For example instead of @Named("maxWaitTime") you could have @MaxWaitTime. It's just a little cleaner. – sourcedelica Mar 24 '11 at 13:07
  • 30
    Nice article about `@Named` and `@Qualifier` http://java.dzone.com/articles/java-ee6-cdi-named-components – xmedeko Sep 19 '12 at 09:36
  • 1
    I don't understand... can't you tell the difference between them by their different variable names? – CodyBugstein May 11 '14 at 17:40
  • Doesn't the fact that the variable is named `maxWaitTimeMs` tell the injector which `long` to bind to which variable? Why do we need both a `@Named` and a variable name? – CodyBugstein Jun 16 '14 at 13:43
  • no, you can't use the variable names for that. variable names aren't always available at run time. java 8 makes this a little better, http://openjdk.java.net/jeps/118 – sbridges Jun 17 '14 at 15:11
  • *Field* names are always available at runtime, in any version of Java. The reason annotations like `@Named` and `@Qualifier` are useful is that you may have different injection points (usually fields) of the same type *and* name, but in *different* scopes (ie, different owner classes); in such a case, the name provided in the qualifier is used by the DI container to choose between multiple injectable beans/values of the same type. – Rogério Oct 09 '15 at 15:12
  • @sbridges Hi, I just want to know for sure that if there is only one implementation of a certain interface, is `@named` still required for that implementation? Can I just use `@Inject` (without using `@named`) to inject the implementation to a variable of the corresponding interface? I know for Spring, you need to mark a class as component in order for the bean to be created. Does the same rule apply here? Thanks! – Dreamer Jul 31 '18 at 07:14
82

@Inject instead of Spring’s @Autowired to inject a bean.
@Named instead of Spring’s @Component to declare a bean.

Those JSR-330 standard annotations are scanned and retrieved the same way as Spring annotation (as long as the following jar is in your classpath)

Raul Cacacho
  • 267
  • 1
  • 4
  • 15
Nadav Finish
  • 1,120
  • 9
  • 7
8

Regarding #2, according to the JSR-330 spec:

This package provides dependency injection annotations that enable portable classes, but it leaves external dependency configuration up to the injector implementation.

So it's up to the provider to determine which objects are available for injection. In the case of Spring it is all Spring beans. And any class annotated with JSR-330 annotations are automatically added as Spring beans when using an AnnotationConfigApplicationContext.

sourcedelica
  • 23,940
  • 7
  • 66
  • 74
6

The primary role of the @Named annotation is to define a bean for the purpose of resolving EL statements within the application, usually through JSF EL resolvers. Injection can be performed using names but this was not how injection in CDI was meant to work since CDI gives us a much richer way to express injection points and the beans to be injected into them.

abbas
  • 6,453
  • 2
  • 40
  • 36