加我微信公衆號,一塊兒夯實Java基礎,向着詩和遠方出發吧~vue
若是全部的裝配工做都交給Spring來自動完成,減小人工的干預,是否是就能減小依賴關係配置帶來的麻煩呢?認真作本身的事兒吧,裝配交給Spring來!java
經過使用Spring的自動裝配,咱們再也不須要去管對象之間複雜的依賴關係,能更加專一於應用核心邏輯的開發。接下來進入我的的free style!各位觀衆把鍋接好了!spring
Spring經過組件掃描和自動裝配實現自動化裝配Bean,經過自動化裝配,能最大程度的減小各類顯式配置。數組
組件掃描默認是不開啓的,所以須要咱們手動去啓動。Spring開啓組件掃描有如下兩種方式。安全
package com.lurker.springaction.yjiang.autowire;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
/** * 經過@Configuration註解,說明該類是一個配置類,配置信息從這裏加載 * 經過@ComponentScan註解,說明開啓組件掃描,默認掃描的是該配置類所在包及其子包 */
@Configuration
@ComponentScan
public class ComponentScanConfig {
}
定義組件掃描的基礎包微信
若是咱們但願把配置類與核心代碼類放在不一樣的包中,這時候默認的加載地址對咱們就沒有意義了。這時候咱們能夠自定義組件掃描的基礎包。有如下兩種方式:markdown
(1) 指明須要掃描的包的名稱架構
package com.lurker.springaction.yjiang.autowire;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
//指明掃描com.lurker.springaction.yjiang.autowire包
//或者不用value,而使用basePackages,效果是同樣的
//value和basePackages都支持以數組的形式配置
//示例:value={"com.lurker.springaction.yjiang.autowire", "..."}
@ComponentScan(value = "com.lurker.springaction.yjiang.autowire")
public class ComponentScanConfig {
}
可是以上方式有個明顯的缺陷,其是類型不安全的,若是某次重構代碼的時候,包名可能會改變,那麼這裏設置的value
或basePackages
就須要改變了。若是你設置了多個多個配置類,想一想,多麼可怕?那麼咱們來個更實用的。app
(2) 指明須要掃描的包中的某個接口學習
package com.lurker.springaction.yjiang.autowire;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
//經過basePackageClasses屬性,指明須要掃描的包中的接口
//該方式一樣支持以數組的形式配置
//示例basePackageClasses={BasePackageLocation.class, ...}
@Configuration
@ComponentScan(basePackageClasses = BasePackageLocation.class)
public class ComponentScanConfig {
}
以上方式,用basePackageClasses
代替了value
和basePackages
屬性。程序在解析的時候,會以BasePackageLocation類所在的路徑做爲基礎包路徑。
咱們通常採用第二種方式進行配置,一般的作法是,在須要掃描的包下創建一個空接口,什麼都不寫。經過標記接口的形式找到基礎包,同時因爲是空接口,你在重構時能夠不加理會,這種方式是對重構友好的。
經過在Spring的xml配置文件中添加以下元素:
<context:component-scan base-package="com.lurker.springaction.yjiang.autowire">
經過這種方式可以取得跟Java配置相同的效果。同時,這種方式也支持同時配置多個包。
開啓了Spring的組件掃描以後,能夠進行掃描指定的包及其子包了。那麼,Spring怎麼知道哪些纔是Bean呢?實際上,Spring的組件是有一個標誌的。
package com.lurker.springaction.yjiang.autowire;
import org.springframework.stereotype.Component;
//@Component註解表示該類會做爲一個組件類,並告訴Spring要爲這個類建立Bean
@Component
public class CDPlayer implements Player {
}
除了@Component
註解外,還有三個註解一樣擁有@Component
的做用,他們分別是:
這三個註解繼承自@Component
註解,所以具備相同的功效。在分層架構體系下,在不一樣的層級運用不一樣名稱的註解,使項目結構更加清晰。
然而注意,這些標註組件的註解,會默認給組件一個名稱,默認爲類名首字母小寫,如其上的Bean名稱爲cDPlayer
;Java中是容許在不一樣的包中有相同類名的,這時候怎麼區分具備相同類名的Bean呢?Spring的解決方案是:
在@Component
、@Controller
、@Service
、@Repository
這些註解中,填寫value
字段,以下:
package com.lurker.springaction.yjiang.autowire;
import org.springframework.stereotype.Component;
//@Component註解表示該類會做爲一個組件類,並告訴Spring要爲這個類建立Bean
@Component(value="player")
public class CDPlayer implements Player {
}
以上代碼,把這個Bean的名稱定義爲player
,而再也不是默認名稱cDPlayer
了。除此以外,JDI規範(Java Dependency Injection)還定義了@Named
註解用於爲Bean設置ID,其具備與@Component(value="player")
相同的功效。例如:
@Named(value="player")
public class CDPlayer implements Player {
}
萬事俱備,只欠東風。Spring已經掃描到了進行標註後的Bean,並已經將他們放入容器中了,怎麼把Bean裝配到須要的地方呢?
Spring經過@Autowired
註解來實現Bean的自動裝配。@Autowired
註解能夠用在類的任何地方。可是,請注意,若是在裝配過程當中,若是某個須要的Bean不存在,那麼Spring會拋出一個異常。若是這個欠缺的Bean不是那麼重要,那麼你能夠嘗試經過required
設置爲false
來忽略掉它不存在的事實。
package com.lurker.springaction.yjiang.autowire;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class CDPlayer {
private Disk disk;
@Autowired
public CDPlayer(Disk disk) {
this.disk = disk;
}
public Disk getDisk() {
return disk;
}
public void setDisk(Disk disk) {
this.disk = disk;
}
}
package com.lurker.springaction.yjiang.autowire;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class CDPlayer {
private Disk disk;
public CDPlayer(Disk disk) {
this.disk = disk;
}
public Disk getDisk() {
return disk;
}
@Autowired
public void setDisk(Disk disk) {
this.disk = disk;
}
}
package com.lurker.springaction.yjiang.autowire;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class CDPlayer {
@Autowired
private Disk disk;
public CDPlayer(Disk disk) {
this.disk = disk;
}
public Disk getDisk() {
return disk;
}
public void setDisk(Disk disk) {
this.disk = disk;
}
}
package com.lurker.springaction.yjiang.autowire;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class CDPlayer {
@Autowired
public void play(Disk disk) {
System.out.println(disk.toString());
}
}
package com.lurker.springaction.yjiang.autowire;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class CDPlayer {
@Autowired(required=false)
public void play(Disk disk) {
System.out.println(disk.toString());
}
}
除此以外,JDI也提供了@Inject
來實現和@Autowired
相同的功能。若是你不想太依賴Spring的註解的話,也可使用@Inject
註解來實現自動裝配。
本文,咱們與代碼結合,實現了Bean的自動化裝配。實際上,這樣作咱們經過極少的配置就可以讓Spring幫咱們進行Bean的管理,何樂而不爲呢?這種配置方式也是咱們主推的。
下一節,咱們將一塊兒探討經過Java配置的方式來進行Bean的裝配。一塊兒期待吧!!!
生命不止,學習不休,加油!!!