官术网_书友最值得收藏!

2.1.1 字段注入

首先,我們來看字段注入。想要在一個類中通過字段的形式注入某個對象,就可以使用這個方式,示例代碼如代碼清單2-2所示。

代碼清單2-2 字段注入示例代碼

public class ClientService {
    @Autowired
    private HealthRecordService healthRecordService;
    public void recordUserHealthData() {
        healthRecordService.recordUserHealthData();
    }
}

可以看到,通過@Autowired注解,字段注入的實現方式非常簡單而直接,代碼的可讀性也很高。事實上,字段注入是三種注入方式中最常用,也是最容易使用的一種,但它也是三種注入方式中最應該避免使用的。如果你使用過IDEA,可能會遇到“Field injection is not recommended”這個提示,告訴你不建議使用字段注入。針對這一點,你可能會覺得很詫異。我們來分析一下原因。

1)字段注入的最大問題是對象的外部可見性。正如在前面的ClientService類中,我們通過定義一個私有變量healthRecordService來注入該接口的實例。顯然,這個實例只能在ClientService類中被訪問,脫離了容器環境就無法進行訪問,如代碼清單2-3所示。

代碼清單2-3 脫離容器使用ClientService示例代碼

ClientService clientService = new ClientService();
clientService.recordUserHealthData();

執行這段代碼的結果就是拋出一個NullPointerException空指針異常,原因是無法在ClientService的外部實例化HealthRecordService對象。采用字段注入,類與容器的耦合度過高,我們無法脫離容器來使用目標對象。如果我們編寫測試用例來驗證ClientService類的正確性,那么想要使用HealthRecordService對象,就只能通過反射的方式,這種做法實際上是不符合JavaBean開發規范的,而且可能導致一直無法發現空指針異常。

2)字段注入的第二個問題是可能導致潛在的循環依賴。所謂循環依賴,就是兩個類之間互相進行注入,示例代碼如代碼清單2-4所示。

代碼清單2-4 基于字段注入的循環依賴示例代碼

public class ClassA {
    @Autowired
    private ClassB classB;
}

public class ClassB {
    @Autowired
    private ClassA classA;
}

顯然,這里的ClassA和ClassB發生了循環依賴。上述代碼在Spring中是合法的,容器啟動時并不會報任何錯誤,而只有在使用到具體某個ClassA或ClassB時才會報錯。

3)字段注入的第三個問題是我們無法設置需要注入的對象為final,也無法注入那些不可變對象,這是因為字段必須在類實例化時進行實例化。

基于以上三點,IDEA以及Spring官方都不推薦開發人員使用字段注入這種方式。那么,我們推薦的注入方式是哪種呢?答案是構造器注入。

主站蜘蛛池模板: 浦江县| 池州市| 南皮县| 晋城| 九江市| 南雄市| 渝北区| 湄潭县| 巴楚县| 湾仔区| 黄陵县| 玛多县| 峨眉山市| 轮台县| 元谋县| 衡阳县| 安庆市| 西贡区| 赫章县| 赣榆县| 鄯善县| 泸西县| 从江县| 常宁市| 玉龙| 都江堰市| 北安市| 平安县| 青阳县| 眉山市| 宿迁市| 揭阳市| 忻州市| 内江市| 武安市| 华容县| 察哈| 万山特区| 乌鲁木齐县| 云南省| 炉霍县|