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
CSDN: https://blog.csdn.net/liyong1028826685
微信公眾號:
技術交流群: