只因多看了一眼提示,又一次刷新了@Autowired註釋的認知

@Autowired和@Resource都可以用於來實現依賴注入,但前者是Spring提供的,後者爲JDK(JSR-250標準)自帶的。阿里Java開發規範中推薦使用@Resource。但大多數人往往並沒有留意爲何如此,甚至代碼中的提示信息可能都沒留意去看。

本文就帶大家徹底瞭解一下這兩個註解的功能、運用場景及區別。

IDE的提示

如果在項目中使用@Autowired進行注入,如下代碼:

@RestController
public class InjectController {
    @Autowired
    private ConnectService connectService;
}

會有這樣的提示信息:

Field injection is not recommended 
Inspection info: Spring Team recommends: "Always use constructor based dependency injection in your beans. Always use assertions for mandatory dependencies".

翻譯過來就是:字段注入是不推薦的,Spring團隊建議:“始終在bean中使用基於構造函數的依賴項注入。始終對強制性依賴項使用斷言”。

根據提示,我們來重新寫一種注入方式:

@RestController
public class InjectController {

    private ConnectService connectService;

    @Autowired
    public void setConnectService(ConnectService connectService) {
        this.connectService = connectService;
    }
}

上面將@Autowired的註解使用在了setter方法上,此時提示消失了。再看另外一種注入方式:

@RestController
public class InjectController {

    private ConnectService connectService;

    @Autowired
    public InjectController(ConnectService connectService) {
        this.connectService = connectService;
    }
}

此種方式將@Autowired的註解使用在了構造方法上,與Spring團隊的建議一致。此時,也不會再出現警告信息。

也就是說IDE提示的信息並不是說不建議大家使用@Autowired註解,而且不要直接使用在字段(Field)上。

Spring注入的方式及場景

Spring常見的DI方式:構造器注入、Setter注入、字段注入。顯然,我們經常使用的方式並不是官方最推薦的。

而上面三種注入方式所適用的場景也是有所區別的:1、構造器注入適用具有強依賴和不變性的依賴;2、Setter注入適用於具有可選性和可變性的依賴注入;3、Field注入,儘量少使用,如果需要則使用@Resource進行替代,以降低耦合性。

Field注入的缺點

Field注入的缺點很明顯,比如不能像構造器注入那樣注入不可變的對象,依賴對外部不可見(構造器和Setter可見,而private的屬性不可見),會導致組件與IoC容器(比如Spring)緊密耦合,單元測試也需要使用IoC容器,依賴過多時相對構造器注入不能夠明顯的看出依賴過多(違反單一職責原則)。

既然Field注入這麼多缺點,但爲什麼大家還是習慣使用呢?主要原因:太方便了,極大的縮減了代碼。而且大多數業務並不需要用構造器強綁定,同時換IoC容器的可能性也極低。所以,雖然官方及IDE一直強調和提醒,但貌似並沒有阻止程序員的使用。

爲什麼只對@Autowired警告

最主要的原因是:@Autowired是Spring提供的,是特定IoC提供的特定註解,與框架形成了強綁定,一旦換用其他IoC框架,是無法支持注入的。而@Resource是JSR-250提供的,IoC容器應當去兼容它,即使更換容器,也可以正常工作。

另外可能還跟這兩種註解的工作機制有關。默認情況下@Autowired是以類型(ByType)進行匹配的,@Resource是以名字(ByName)進行匹配的。也就是說當容器中存在兩個相同類型的Bean時,使用@Autowired注入會報錯,而使用@Resource會更精準。當然@Autowired也可以指定名稱(還需配合@Qualifier註解)。

@Autowired和@Resource功能

就Spring而言,不但支持自定義的@Autowired註解,還支持幾個由JSR-250規範定義的註解,分別爲@Resource、@PostConstruct以及@PreDestroy。

而@Autowired和@Resource的功能基本一致,@Resource的作用相當於@Autowired,只不過@Autowired默認按byType自動注入,而@Resource默認按byName自動注入。

@Resource有兩個核心屬性:name和type。Spring將@Resource註解的name屬性解析爲bean的名字,type屬性則解析爲bean的類型。默認情況下會通過反射機制使用byName自動注入策略。

@Resource裝配場景:

  • 1、如果同時指定了name和type,則從Spring上下文中找到唯一匹配的bean進行裝配,找不到則拋出異常;
  • 2、如果指定了name,則根據名稱進行裝配,找不到則拋出異常;
  • 3、如果指定了type,則根據類型進行裝配,找不到或者找到多個,都會拋出異常;
  • 4、沒有任何指定(默認情況),則採用byName方式進行裝配,如果沒有匹配到,則回退爲一個原始類型進行匹配;

小結

處於對代碼的潔癖,不習慣@Autowired的提示信息,於是整個項目中都強力推薦使用@Resource註解。瞭解了這一提示的底層原理,或許你就可以選擇最適合自己的注入形式了。

作者:程序新視界
原文鏈接:https://hello.blog.csdn.net/article/details/111307184

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章