从Spring3.0之后,Spring提供了JSR-330标志注解的支持。这些注解和Spring注解一样被进行扫描,如果想使用它们,需要包含下面的jar包:
如果你使用maven,那么javax.inject工件可以在标准maven存储库中使用(https://repo1.maven.org/maven2/javax/inject/javax.inject/1/)。可以将以下依赖项添加到文件pom.xml中:
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
你可以使用 @javax.inject.Inject来替代@Autowired:
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(...);
...
}
}
与@Autowired一样,你可以在字段级、方法级和构造函数参数级使用@Inject。此外,你可以将注入点声明为Provider,允许通过Provider.get() 调用按需访问较短作用域的bean或延迟访问其他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(...);
...
}
}
如果要对应注入的依赖项使用限定名,则应使用@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;
}
// ...
}
与@Autowired一样,@Inject也可以与java.util.Optional或@Nullable一起使用。这在这里更适用,因为@Jnject没有required的属性。以下两个示例演示如何使用@Inject和@Nullable:
public class SimpleMovieLister {
@Inject
public void setMovieFinder(Optional<MovieFinder> movieFinder) {
...
}
}
public class SimpleMovieLister {
@Inject
public void setMovieFinder(@Nullable MovieFinder movieFinder) {
...
}
}
除了使用@Component,你也可以使用@javax.inject.Named 或者 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;
}
// ...
}
在不指定组件名称的情况下使用@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;
}
// ...
}
当你使用@Named或者@ManagedBean,你可以同样使用组件扫描:
@Configuration
@ComponentScan(basePackages = "org.example")
public class AppConfig {
...
}
与@Component不同,JSR-330的@Named和JSR-250的@ManagedBean是不可组合的。你应该使用Spring的构造型模型来构建自定义组件注解。
当使用标准注解时,你应该知道一些重要功能不可用,如下表所示:
Spring | javax.inject.* | javax.inject限制/描述 |
---|---|---|
@Autowired | @Inject | @Inject没有required属性,可以使用Java8的Optional代替 |
@Component | @Named / @ManagedBean | JSR-330没有提供组合模式,只有一种方式来标记命名组件 |
@Scope("singleton") | @Singleton | JSR-330默认范围像Spring的prototype,但是为了和Spring的默认值保持一致,在Spring中定义的JSR-330 bean默认是singleton。如果要使用其他的作用范围,那么需要使用Spring的@Scope注解。javax.inject也提供了一个@Scope注解。但是这个注解仅用来创建你自己的注解。 |
@Qualifier | @Qualifier / @Named | javax.inject.Qualifier只是一个用来构建自定义Qualifier的元注解。具体的字符串限定符(如带value的Spring的@Qualifier)可以通过javax.inject.Named关联。 |
@Value | - | 没有相同功能 |
@Required | - | 没有相同功能 |
@Lazy | - | 没有相同功能 |
ObjectFactory | Provider | javax.inject.Provider是Spring的ObjectFactory的直接替代品,它只使用了较短的get()方法名。它还可以与Spring的@Autowired结合使用,或者与无注解的构造函数和setter方法结合使用。 |