JSR 330标准注释
从Spring 3.0开始,Spring提供对JSR-330标准注释(依赖注入)的支持。这些注释以与Spring注释相同的方式进行扫描。你只需要在你的类路径中有相关的jar。
如果您使用的是Maven,javax.inject则可以在标准Maven存储库中使用该工件( http://repo1.maven.org/maven2/javax/inject/javax.inject/1/)。您可以将以下依赖项添加到您的文件pom.xml中:
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
一、依赖注入@Inject和@Named
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
可以用在字段级别、方法级别和构造函数参数级别。此外,你还可以将切入点声明为a Provider
。
此外,您可以将注入点声明为a 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(...);
...
}
}
如果您想为应该注入的依赖项使用限定名称,则应该@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。这在这里更加适用,因为@Inject它没有required属性。
- Optional
public class SimpleMovieLister {
@Inject
public void setMovieFinder(Optional<MovieFinder> movieFinder) {
...
}
}
- @Nullable
public class SimpleMovieLister {
@Inject
public void setMovieFinder(@Nullable MovieFinder movieFinder) {
...
}
}
二、@Named和@ManagedBean:@Component注解的标准等价物
在这里不使用@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,可以像使用Spring注释时一样使用组件扫描:
@Configuration
@ComponentScan(basePackages = "org.example")
public class AppConfig {
...
}
相比之下@Component,JSR-330 @Named和JSR-250 ManagedBean 注释不可组合。请使用Spring的构造型模型来构建自定义组件注释。
三、JSR-330标准注释的局限性
在使用标准注释时,重要的是要知道一些重要的功能不可用,如下表所示:
表6. Spring组件模型元素与JSR-330变体的比较
Spring | javax.inject.* | javax.inject restrictions(限制条件) / comments |
---|---|---|
@Autowired | @Injec | @Inject没有“必需”属性; 可以与Java 8一起使用Optional。 |
@Component | @Named / @ManagedBean | JSR-330不提供可组合模型,只是识别命名组件的一种方法。 |
@Scope(“singleton”) | @Singleton | JSR-330的默认范围就像Spring’s一样prototype。然而,为了保持它与Spring的一般默认值一致,Spring容器中声明的JSR-330 bean是singleton默认的。为了使用除singleton以外的作用域,你应该使用Spring的@Scope注解。javax.inject还提供了 @Scope注释。尽管如此,这只是用来创建自己的注释。 |
@Qualifier | @Qualifier / @Named | javax.inject.Qualifier只是构建自定义限定符的元注释。具体的字符串限定符(像Spring的@Qualifier值)可以通过关联javax.inject.Named。 |
@Value | no equivalent | |
@Required | no equivalent | |
@Lazy | no equivalent | |
ObjectFactory | Provider | javax.inject.Provider是Spring的一个直接替代方法ObjectFactory,只需要一个较短的get()方法名称。它也可以与Spring组合使用,@Autowired或者使用未注释的构造函数和setter方法。 |
好了,Spring中的JSR 330注释就讲到这里啦。