Using JSR 330 Standard Annotations
Spring 为 JSR-330 标准注解提供支持(依赖项注入)。这些注解的扫描方式与 Spring 注解相同。要使用它们,你需要在类路径中包含相关 jar。
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.
如果你使用 Maven, If you use Maven, the
|
Dependency Injection with @Inject
and @Named
代替 @Autowired
,你可以使用 @jakarta.inject.Inject
,如下所示:
Instead of @Autowired
, you can use @jakarta.inject.Inject
as follows:
-
Java
-
Kotlin
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(...)
// ...
}
}
与 @Autowired
一样,你可以在字段级别、方法级别和构造函数参数级别使用 @Inject
。此外,你可以将注入点声明为 Provider
,允许按需访问较短作用域的 bean,或者通过 Provider.get()
调用来延迟访问其他 bean。以下示例提供了上述示例的一个变体:
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
-
Kotlin
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(...)
// ...
}
}
如果你想为应该注入的依赖项使用限定名,那么你应该使用 @Named
注解,如下例所示:
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
-
Kotlin
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
}
// ...
}
与 @Autowired
一样,@Inject
也可以与 java.util.Optional
或`@Nullable` 一起使用。由于 @Inject
没有`required` 属性,所以在这种情况适用性更强。以下示例对展示如何使用 @Inject
和`@Nullable`:
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
-
Kotlin
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
可以使用 @jakarta.inject.Named
或 jakarta.annotation.ManagedBean
代替 @Component
,如下例所示:
Instead of @Component
, you can use @jakarta.inject.Named
or jakarta.annotation.ManagedBean
,
as the following example shows:
-
Java
-
Kotlin
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
// ...
}
经常在不为组件指定名称的情况下使用 @Component
。@Named
可以以类似的方式使用,如下例所示:
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
-
Kotlin
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
// ...
}
使用 @Named
或 @ManagedBean
时,可以与使用 Spring 注解时完全相同的方式使用组件扫描,如下例所示:
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
-
Kotlin
@Configuration
@ComponentScan(basePackages = "org.example")
public class AppConfig {
// ...
}
@Configuration
@ComponentScan(basePackages = ["org.example"])
class AppConfig {
// ...
}
不同于`@Component`,JSR-330 `@Named`和JSR-250 `@ManagedBean`注解不可组合。您应该使用 Spring 的模式模型来构建自定义组件注解。 |
In contrast to |
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 | jakarta.inject.* | jakarta.inject restrictions / comments |
---|---|---|
@Autowired |
@Inject |
|
@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 |
@Qualifier |
@Qualifier / @Named |
|
@Value |
- |
no equivalent |
@Lazy |
- |
no equivalent |
ObjectFactory |
Provider |
|