Using JSR 330 Standard Annotations

Starting with Spring 3.0, Spring offers support for JSR-330 standard annotations (Dependency Injection). Those annotations are scanned in the same way as the Spring annotations. To use them, you need to have the relevant jars in your classpath.

If you use Maven, the javax.inject artifact is available in the standard Maven repository ( https://repo1.maven.org/maven2/javax/inject/javax.inject/1/). You can add the following dependency to your file pom.xml:

<dependency>
	<groupId>javax.inject</groupId>
	<artifactId>javax.inject</artifactId>
	<version>1</version>
</dependency>

Dependency Injection with @Inject and @Named

Instead of @Autowired, you can use @javax.inject.Inject as follows:

Java
import javax.inject.Inject;

public class SimpleMovieLister {

	private MovieFinder movieFinder;

	@Inject
	public void setMovieFinder(MovieFinder movieFinder) {
		this.movieFinder = movieFinder;
	}

	public void listMovies() {
		this.movieFinder.findMovies(...);
		// ...
	}
}
Kotlin
import javax.inject.Inject

class SimpleMovieLister {

	@Inject
	lateinit var movieFinder: MovieFinder


	fun listMovies() {
		movieFinder.findMovies(...)
		// ...
	}
}

As with @Autowired, you can use @Inject at the field level, method level and constructor-argument level. Furthermore, you may declare your injection point as a Provider, allowing for on-demand access to beans of shorter scopes or lazy access to other beans through a Provider.get() call. The following example offers a variant of the preceding example:

Java
import javax.inject.Inject;
import javax.inject.Provider;

public class SimpleMovieLister {

	private Provider<MovieFinder> movieFinder;

	@Inject
	public void setMovieFinder(Provider<MovieFinder> movieFinder) {
		this.movieFinder = movieFinder;
	}

	public void listMovies() {
		this.movieFinder.get().findMovies(...);
		// ...
	}
}
Kotlin
import javax.inject.Inject

class SimpleMovieLister {

	@Inject
	lateinit var movieFinder: MovieFinder


	fun listMovies() {
		movieFinder.findMovies(...)
		// ...
	}
}

If you would like to use a qualified name for the dependency that should be injected, you should use the @Named annotation, as the following example shows:

Java
import javax.inject.Inject;
import javax.inject.Named;

public class SimpleMovieLister {

	private MovieFinder movieFinder;

	@Inject
	public void setMovieFinder(@Named("main") MovieFinder movieFinder) {
		this.movieFinder = movieFinder;
	}

	// ...
}
Kotlin
import javax.inject.Inject
import javax.inject.Named

class SimpleMovieLister {

	private lateinit var movieFinder: MovieFinder

	@Inject
	fun setMovieFinder(@Named("main") movieFinder: MovieFinder) {
		this.movieFinder = movieFinder
	}

	// ...
}

As with @Autowired, @Inject can also be used with java.util.Optional or @Nullable. This is even more applicable here, since @Inject does not have a required attribute. The following pair of examples show how to use @Inject and @Nullable:

public class SimpleMovieLister {

	@Inject
	public void setMovieFinder(Optional<MovieFinder> movieFinder) {
		// ...
	}
}
Java
public class SimpleMovieLister {

	@Inject
	public void setMovieFinder(@Nullable MovieFinder movieFinder) {
		// ...
	}
}
Kotlin
class SimpleMovieLister {

	@Inject
	var movieFinder: MovieFinder? = null
}

@Named and @ManagedBean: Standard Equivalents to the @Component Annotation

Instead of @Component, you can use @javax.inject.Named or javax.annotation.ManagedBean, as the following example shows:

Java
import javax.inject.Inject;
import javax.inject.Named;

@Named("movieListener")  // @ManagedBean("movieListener") could be used as well
public class SimpleMovieLister {

	private MovieFinder movieFinder;

	@Inject
	public void setMovieFinder(MovieFinder movieFinder) {
		this.movieFinder = movieFinder;
	}

	// ...
}
Kotlin
import javax.inject.Inject
import javax.inject.Named

@Named("movieListener")  // @ManagedBean("movieListener") could be used as well
class SimpleMovieLister {

	@Inject
	lateinit var movieFinder: MovieFinder

	// ...
}

It is very common to use @Component without specifying a name for the component. @Named can be used in a similar fashion, as the following example shows:

Java
import javax.inject.Inject;
import javax.inject.Named;

@Named
public class SimpleMovieLister {

	private MovieFinder movieFinder;

	@Inject
	public void setMovieFinder(MovieFinder movieFinder) {
		this.movieFinder = movieFinder;
	}

	// ...
}
Kotlin
import javax.inject.Inject
import javax.inject.Named

@Named
class SimpleMovieLister {

	@Inject
	lateinit var movieFinder: MovieFinder

	// ...
}

When you use @Named or @ManagedBean, you can use component scanning in the exact same way as when you use Spring annotations, as the following example shows:

Java
@Configuration
@ComponentScan(basePackages = "org.example")
public class AppConfig  {
	// ...
}
Kotlin
@Configuration
@ComponentScan(basePackages = ["org.example"])
class AppConfig  {
	// ...
}
In contrast to @Component, the JSR-330 @Named and the JSR-250 ManagedBean annotations are not composable. You should use Spring’s stereotype model for building custom component annotations.

Limitations of JSR-330 Standard Annotations

When you work with standard annotations, you should know that some significant features are not available, as the following table shows:

Table 1. Spring component model elements versus JSR-330 variants
Spring javax.inject.* javax.inject restrictions / comments

@Autowired

@Inject

@Inject has no 'required' attribute. Can be used with Java 8’s Optional instead.

@Component

@Named / @ManagedBean

JSR-330 does not provide a composable model, only a way to identify named components.

@Scope("singleton")

@Singleton

The JSR-330 default scope is like Spring’s prototype. However, in order to keep it consistent with Spring’s general defaults, a JSR-330 bean declared in the Spring container is a singleton by default. In order to use a scope other than singleton, you should use Spring’s @Scope annotation. javax.inject also provides a @Scope annotation. Nevertheless, this one is only intended to be used for creating your own annotations.

@Qualifier

@Qualifier / @Named

javax.inject.Qualifier is just a meta-annotation for building custom qualifiers. Concrete String qualifiers (like Spring’s @Qualifier with a value) can be associated through javax.inject.Named.

@Value

-

no equivalent

@Required

-

no equivalent

@Lazy

-

no equivalent

ObjectFactory

Provider

javax.inject.Provider is a direct alternative to Spring’s ObjectFactory, only with a shorter get() method name. It can also be used in combination with Spring’s @Autowired or with non-annotated constructors and setter methods.