大數據

Spring 5 中文解析核心篇-IoC容器之JSR330標準註解

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.Namedjavax.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-250 ManagedBean註解是不能被組合的。你應該使用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

微信公眾號:

技術交流群:

Leave a Reply

Your email address will not be published. Required fields are marked *