This version is still in development and is not considered stable yet. For the latest stable version, please use Spring Framework 6.2.0!spring-doc.cn

Using JSR 330 Standard Annotations

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.spring-doc.cn

If you use Maven, the jakarta.inject artifact is available in the standard Maven repository ( https://repo.maven.apache.org/maven2/jakarta/inject/jakarta.inject-api/2.0.0/). You can add the following dependency to your file pom.xml:spring-doc.cn

<dependency>
	<groupId>jakarta.inject</groupId>
	<artifactId>jakarta.inject-api</artifactId>
	<version>2.0.0</version>
</dependency>

Dependency Injection with @Inject and @Named

Instead of @Autowired, you can use @jakarta.inject.Inject as follows:spring-doc.cn

import jakarta.inject.Inject;

public class SimpleMovieLister {

	private MovieFinder movieFinder;

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

	public void listMovies() {
		this.movieFinder.findMovies(...);
		// ...
	}
}
import jakarta.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:spring-doc.cn

import jakarta.inject.Inject;
import jakarta.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(...);
		// ...
	}
}
import jakarta.inject.Inject

class SimpleMovieLister {

	@Inject
	lateinit var movieFinder: Provider<MovieFinder>


	fun listMovies() {
		movieFinder.get().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:spring-doc.cn

import jakarta.inject.Inject;
import jakarta.inject.Named;

public class SimpleMovieLister {

	private MovieFinder movieFinder;

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

	// ...
}
import jakarta.inject.Inject
import jakarta.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:spring-doc.cn

public class SimpleMovieLister {

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

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

	@Inject
	var movieFinder: MovieFinder? = null
}

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

Instead of @Component, you can use @jakarta.inject.Named or jakarta.annotation.ManagedBean, as the following example shows:spring-doc.cn

import jakarta.inject.Inject;
import jakarta.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;
	}

	// ...
}
import jakarta.inject.Inject
import jakarta.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:spring-doc.cn

import jakarta.inject.Inject;
import jakarta.inject.Named;

@Named
public class SimpleMovieLister {

	private MovieFinder movieFinder;

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

	// ...
}
import jakarta.inject.Inject
import jakarta.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:spring-doc.cn

@Configuration
@ComponentScan(basePackages = "org.example")
public class AppConfig  {
	// ...
}
@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:spring-doc.cn

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

@Autowiredspring-doc.cn

@Injectspring-doc.cn

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

@Componentspring-doc.cn

@Named / @ManagedBeanspring-doc.cn

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

@Scope("singleton")spring-doc.cn

@Singletonspring-doc.cn

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. jakarta.inject also provides a jakarta.inject.Scope annotation: however, this one is only intended to be used for creating custom annotations.spring-doc.cn

@Qualifierspring-doc.cn

@Qualifier / @Namedspring-doc.cn

jakarta.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 jakarta.inject.Named.spring-doc.cn

@Valuespring-doc.cn

-spring-doc.cn

no equivalentspring-doc.cn

@Lazyspring-doc.cn

-spring-doc.cn

no equivalentspring-doc.cn

ObjectFactoryspring-doc.cn

Providerspring-doc.cn

jakarta.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.spring-doc.cn