1.11 使用JSR330标准注解
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>
1.11.1 @Inject
和@Named
依赖注入
你可以使用@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
,从而允许按需访问范围较短的bean,或者通过提供程序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
属性。下面两个例子展示怎样去使用@Inject
和@Nullable
:
public class SimpleMovieLister {
@Inject
public void setMovieFinder(Optional<MovieFinder> movieFinder) {
// ...
}
}
public class SimpleMovieLister {
@Inject
public void setMovieFinder(@Nullable MovieFinder movieFinder) {
// ...
}
}
参考代码:
com.liyong.ioccontainer.starter.XmlInjectAndNamedIocContainer
1.11.2 @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
相比,JSR330@Named
和JSR-250ManagedBean
注解是不能被组合的。你应该使用Spring的构造型模型来构建自定义组件注解。
参考代码:
com.liyong.ioccontainer.starter.XmlNamedAndManagerBeanIocContainer
1.11.3 JSR-330标准注解的限制
当你使用标准注解时,你应该知道一些重要特性不可用,类似下面表格展示:
Spring | javax.inject.* | javax.inject restrictions / comments |
---|---|---|
@Autowired |
@Inject |
@Inject 没有 required 属性. 能够使用在Java8的 Optional 。 |
@Component |
@Named / @ManagedBean |
JSR-330不提供可组合的模型,仅提供一种识别命名组件的方法。 |
@Scope("singleton") |
@Singleton |
JSR-330 默认作用域是 Spring的 prototype . 然而, 为了保存与Spring的一般默认一致性, 在Spring容器中JSR-330bean默认被声明为一个singleton 。为了使用其他的作用域,你应该使用Spring的@Scope 注解。javax.inject也提供一个@Scope 注解。不过,此仅用于创建自己的注解。 |
@Qualifier |
@Qualifier / @Named |
javax.inject.Qualifier 是构建自定义限定符元注解. 具体的 String 限定通过javax.inject.Named 关联。 (类似Spring的 @Qualifier 值) |
@Value |
- | no equivalent |
@Required |
- | no equivalent |
@Lazy |
- | no equivalent |
ObjectFactory |
Provider |
javax.inject.Provider 是Spring的ObjectFactory的直接替代,仅仅有一个get() 方法名,它也可以与Spring的@Autowired 结合使用,也可以与无注释的构造函数和setter方法结合使用。 |
作者
个人从事金融行业,就职过易极付、思建科技、某网约车平台等重庆一流技术团队,目前就职于某银行负责统一支付系统建设。自身对金融行业有强烈的爱好。同时也实践大数据、数据存储、自动化集成和部署、分布式微服务、响应式编程、人工智能等领域。同时也热衷于技术分享创立公众号和博客站点对知识体系进行分享。
博客地址: http://youngitman.tech