從Spring 3.0開始,Spring開始支持JSR-330標(biāo)準(zhǔn)的注解(依賴注入)。這些注解和Spring注解掃描的方式是一直的,開發(fā)者只需要在classpath中配置相關(guān)的jar包即可。
如果開發(fā)者使用Maven來管理項目的話,
javax.injectartifact在Maven倉庫中是可用的(http://repo1.maven.org/maven2/javax/inject/javax.inject/1/)。開發(fā)者只需要在pom中引用這個依賴即可。
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
通過@Inject和@Named進(jìn)行依賴注入
JSR-330中,@javax.inject.Inject和Spring中的@Autowired的職責(zé)相同:
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一致的是,開發(fā)者可以使用@Inject在實例變量,方法以及構(gòu)造參數(shù)級別來使用依賴注入。而且,開發(fā)者可以將注入聲明為Provider,通過Provider.get()來請求那些短作用域或者延遲初始化的Bean。比如如下的例子:
import javax.inject.Inject;
import javax.inject.Provider;
public class SimpleMovieLister {
private Provider<MovieFinder> movieFinder;
public void listMovies() {
this.movieFinder.get().findMovies(...);
...
}
}
如果開發(fā)者希望來通過名字來限定注入的Bean,可以使用@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;
}
// ...
}
@Named:等同于@Component注解
JSR-330中,@javax.inject.Named和Spring中的@Component的職責(zé)類似:
import javax.inject.Inject;
import javax.inject.Named;
@Named("movieListener")
public class SimpleMovieLister {
private MovieFinder movieFinder;
@Inject
public void setMovieFinder(MovieFinder movieFinder) {
this.movieFinder = movieFinder;
}
// ...
}
@Component的使用中經(jīng)常是不需要指定名字的,@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注解的時候,也同樣可以使用組件掃描:
@Configuration
@ComponentScan(basePackages = "org.example")
public class AppConfig {
...
}
和Spring的
@Component組件不同的是,JSR-330的Named注解不可以組合來使用,如果希望自定義組件注解的話,還請使用Spring的組件注解。
JSR-330標(biāo)準(zhǔn)注解的限制
當(dāng)使用JSR-330標(biāo)準(zhǔn)的注解時,了解其和Spring注解的不同點也是十分必要的,參考如下表:
| Spring | javax.inject.* | javax.inject 限制 |
|---|---|---|
| @Autowired | @Inject |
@Inject注解沒有required屬性,但是可以通過Java 8的Optional取代 |
| @Component | @Named | JSR_330標(biāo)準(zhǔn)并沒有提供復(fù)合的模型,只有一種方式來識別組件 |
| @Scope("singleton") | @Singleton | JSR-330默認(rèn)的作用域類似Spring的prototype,然而,為何和Spring的默認(rèn)保持一致,JSR-330標(biāo)準(zhǔn)中的Bean在Spring中默認(rèn)也是單例的。如果要使用非單例的作用域,開發(fā)者應(yīng)該使用Spring的@Scope注解。java.inject也提供一個@Scope注解,然而,這個注解僅僅可以用來創(chuàng)建自定義的作用域時才能使用。 |
| @Qualifier | @Qualifier/@Named |
javax.inject.Qualifier僅僅是一個元注解,用來構(gòu)建自定義限定符的。而String的限定符(比如Spring中的@Qualifier)可以通過javax.inject.Named來實現(xiàn) |
| @Value | - | 不等價 |
| @Required | - | 不等價 |
| @Lazy | - | 不等價 |
| ObjectFactory | Provider |
javax.inject.Provider是SpringObjectFactory的另一個選擇,通過get()方法來代理,Provider可以和Spring的@Autowired組合使用 |