原來(lái) @Autowired 注解還可以這么玩?!
點(diǎn)擊小卡片,快速關(guān)注樓下小黑哥??
Hello,大家好,我是樓下小黑哥~
Spring 是我們平常開(kāi)發(fā)中離不開(kāi)的核心框架,每天開(kāi)發(fā)都在使用 Spring 的功能。
還記得剛開(kāi)始學(xué)習(xí) Spring 的時(shí)候,那個(gè)時(shí)候 Spring 的版本還很低,大概是 Spring 3.X 的版本。那個(gè)時(shí)候 Spring 編程一切都離不開(kāi) XML 文件,所有 Bean 需要在 XML 中定義,也需要通過(guò) XML 方式的注入到起到 Bean 中。
后來(lái),Spring 注解的方式開(kāi)始火了,我們可以直接使用 @Component 等生成 Bean ,也可以直接通過(guò) @Autowired注解的方式注入 Bean。
最近翻看 Spring 的文檔,才發(fā)現(xiàn)原來(lái) @Autowired 注解使用方式還有很多種,有些方式使用起來(lái)很有意思,巧加利用的話,可以非常節(jié)省我們的開(kāi)發(fā)時(shí)間。

@Autowired 字段
我們可以把 @Autowired 注解標(biāo)注在類文件中的字段屬性上,通過(guò)這種方式,Spring 容器啟動(dòng)的時(shí)候會(huì)查找相應(yīng)的 Bean ,然后通過(guò)反射的方式注入到這個(gè)字段中。
例子如下:
@Controller
public class PayController {
@Autowired
PayService aliPayService;
}
這種方式使用起來(lái)非常方便,而且對(duì)于字段的要求也比較低,它可以是 public,也可以是 private范圍。
日常編程中,我一般是直接使用這種方式,簡(jiǎn)潔又便利。
@Autowired 構(gòu)造方法
第二種方式,我們可以使用類中的構(gòu)造函數(shù)注入相應(yīng)屬性,例子如下:
@Controller
public class PayController {
PayService aliPayService;
@Autowired
public PayController(PayService aliPayService) {
this.aliPayService = aliPayService;
}
}
@Autowired 構(gòu)造方法里的傳參,可以是一個(gè),也可以是多個(gè)。如果是多個(gè)參數(shù),那 Spring 一起都注入進(jìn)來(lái)。
@Controller
public class PayController {
PayService aliPayService;
OrderService orderService;
@Autowired
public PayController(PayService aliPayService, OrderService orderService) {
this.aliPayService = aliPayService;
this.orderService=orderService;
}
}
這種方式在注入多個(gè)屬性的時(shí)候用起來(lái)還是比較方便的。
那其實(shí)有一種情況下,如果一個(gè)類不存在無(wú)參的構(gòu)造函數(shù),只存在有參的構(gòu)造函數(shù),那實(shí)際上我們即使不用 @Autowired標(biāo)注,Spring 也會(huì)幫我們注入相應(yīng)的屬性。

可以看到,上面的例子,我們沒(méi)有在構(gòu)造函數(shù)上使用 @Autowired標(biāo)注,但是 IDEA 依然顯示我們成功注入相應(yīng)的屬性。
@Autowired 方法
第三種方式,我們可以通過(guò)方法注入相應(yīng)屬性,例子如下:
@Controller
public class PayController {
PayService aliPayService;
@Autowired
public void setAliPayService(PayService aliPayService) {
this.aliPayService = aliPayService;
}
}
那之前我一直以為這種方式只能使用 setxxx才可以成功的注入屬性 ,那其實(shí)是我理解錯(cuò)了,這個(gè)方法可以任意的命名。
那方法注入,其實(shí)跟構(gòu)造方法一樣,也可以同時(shí)有多個(gè)傳參,Spring 將會(huì)把這些屬性一起注入。

@Autowired 多個(gè) Bean
最后一種方式,Spring 可以使用 @Autowired 標(biāo)注 Array (數(shù)組),Collections(集合),甚至是 Map (散列表),通過(guò)這種命方式注入多個(gè)相同類型的 Bean。
比如這種方式,將 PayService 接口所有實(shí)現(xiàn)類注入到 Array數(shù)組中。

也可以是這種方式,注入到 List 集合中。

上面的兩個(gè)例子,數(shù)組與集合中的 Bean 的順序是根據(jù) Spring 創(chuàng)建的順序。
如果你想指定里面排序的優(yōu)先級(jí),那你就需要使用 @Order或者 @Priority 指定一下優(yōu)先級(jí),比如這樣:

或者這樣:

@Order/Priority 注解中值越小,那它的優(yōu)先級(jí)就越高。
最后我們還可以將 PayService 接口所有實(shí)現(xiàn)類注入到 Map 中,其中里面的 key 就是Spring 的 Bean 的名字。

ps: 使用
@Autowired注入屬性到 Map 中,key必須是String類型。這也可以理解,你要是其他類型,Spring 都不知道去哪里給你找。。。
總結(jié)
@Autowired注解可以把相應(yīng) Bean 注入到相關(guān)屬性中,它的注入方式有很多種。
我們可以使用 @Autowired直接標(biāo)注類中的字段,快速使用。
我們也可以使用 @Autowired 標(biāo)注構(gòu)造方法/普通的方法,這樣可以方便注入多個(gè) Bean。
最后,我們還可以 @Autowired標(biāo)注 Array (數(shù)組),Collections(集合),甚至是 Map (散列表),將所有匹配到的 Bean 注入進(jìn)來(lái)。
那最后一種方式,其實(shí)在某些場(chǎng)景非常有用。比如說(shuō),我們通過(guò) @Autowired將所有匹配到 Bean 注入到 Map 中,利用這個(gè)特性,我們可以快速實(shí)現(xiàn)策略模式。
下篇文章我們就用這個(gè)特性實(shí)現(xiàn)一下,886~
別再這么寫(xiě)代碼了,這幾個(gè)方法不香嗎?
