1.11. Using JSR 330 Standard Annotations
使用 JSR 330 标准注释
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.
从 Spring 3.0 开始,Spring 提供对 JSR-330 标准注解(依赖注入)的支持。这些注释的扫描方式与 Spring 注释相同。要使用它们,您需要在类路径中有相关的 jar。
If you use Maven, the javax.inject artifact is available in the standard Maven repository ( Central Repository: javax/inject/javax.inject/1). You can add the following dependency to your file pom.xml: | |
---|---|
如果您使用 Maven,则该javax.inject 工件在标准 Maven 存储库 ( Central Repository: javax/inject/javax.inject/1 ) 中可用。您可以将以下依赖项添加到文件 pom.xml 中: |
1.11.1. Dependency Injection with @Inject
and @Named
依赖注入@Inject
和@Named
Instead of @Autowired
, you can use @javax.inject.Inject
as follows:
而不是@Autowired
,您可以使用@javax.inject.Inject
如下:
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(...);
// ...
}
}
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:
与 一样@Autowired
,您可以@Inject
在字段级别、方法级别和构造函数参数级别使用。此外,您可以将注入点声明为 Provider
,从而允许按需访问范围更短的 bean 或通过Provider.get()
调用延迟访问其他 bean。以下示例提供了前面示例的变体:
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(...);
// ...
}
}
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:
如果您想为应该注入的依赖项使用限定名称,则应使用@Named
注解,如以下示例所示:
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;
}
// ...
}
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
:
与@Autowired
,@Inject
也可以与java.util.Optional
or 一起使用@Nullable
。这在这里更适用,因为@Inject
没有required
属性。以下一对示例展示了如何使用@Inject
和 @Nullable
:
public class SimpleMovieLister {
@Inject
public void setMovieFinder(Optional<MovieFinder> movieFinder) {
// ...
}
}
public class SimpleMovieLister {
@Inject
public void setMovieFinder(@Nullable MovieFinder movieFinder) {
// ...
}
}
1.11.2. @Named
and @ManagedBean
: Standard Equivalents to the @Component
Annotation
@Named
和:注释@ManagedBean
的标准等效项@Component
Instead of @Component
, you can use @javax.inject.Named
or javax.annotation.ManagedBean
, as the following example shows:
@Component
您可以使用@javax.inject.Named
or代替javax.annotation.ManagedBean
,如以下示例所示:
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;
}
// ...
}
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:
@Component
在不指定组件名称的情况下 使用是很常见的。@Named
可以以类似的方式使用,如以下示例所示:
import javax.inject.Inject;
import javax.inject.Named;
@Named
public class SimpleMovieLister {
private MovieFinder movieFinder;
@Inject
public void setMovieFinder(MovieFinder movieFinder) {
this.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:
使用@Named
or@ManagedBean
时,可以像使用 Spring 注解一样使用组件扫描,如以下示例所示:
@Configuration
@ComponentScan(basePackages = "org.example")
public 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. | |
---|---|
与 相比@Component ,JSR-330@Named 和 JSR-250@ManagedBean 注释是不可组合的。您应该使用 Spring 的原型模型来构建自定义组件注释。 |
1.11.3. Limitations of JSR-330 Standard Annotations
JSR-330 标准注释的限制
When you work with standard annotations, you should know that some significant features are not available, as the following table shows:
当您使用标准注释时,您应该知道某些重要功能不可用,如下表所示:
Spring | javax.inject.* | javax.inject restrictions / comments |
---|---|---|
@Autowired | @Inject | @Inject has no 'required' attribute. Can be used with Java 8’s Optional instead. |
@Inject 没有“必需”属性。可以与 Java 8 一起使用Optional 。 | ||
@Component | @Named / @ManagedBean | JSR-330 does not provide a composable model, only a way to identify named components. |
JSR-330 不提供可组合模型,仅提供一种识别命名组件的方法。 | ||
@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. |
JSR-330 默认范围类似于 Spring 的prototype . 但是,为了保持它与 Spring 的一般默认值一致,在 Spring 容器中声明的 JSR-330 bean 是singleton 默认的。为了使用 以外的范围singleton ,您应该使用 Spring 的@Scope 注解。javax.inject 还提供了一个 @Scope注解。然而,这个仅用于创建您自己的注释。 | ||
@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 . |
javax.inject.Qualifier 只是用于构建自定义限定符的元注释。具体String 的限定符(如@Qualifier 带有值的 Spring)可以通过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. |
javax.inject.Provider 是 Spring 的直接替代品,只是方法名称ObjectFactory 更短。get() 它还可以与 Spring@Autowired 或未注释的构造函数和 setter 方法结合使用。 |