《Spring實戰》讀書筆記——如何實現自動化裝配

加我微信公衆號,一塊兒夯實Java基礎,向着詩和遠方出發吧~vue

若是全部的裝配工做都交給Spring來自動完成,減小人工的干預,是否是就能減小依賴關係配置帶來的麻煩呢?認真作本身的事兒吧,裝配交給Spring來!java

經過使用Spring的自動裝配,咱們再也不須要去管對象之間複雜的依賴關係,能更加專一於應用核心邏輯的開發。接下來進入我的的free style!各位觀衆把鍋接好了!spring

一覽衆山小

  • Spring開啓組件掃描的方式
  • 如何讓Bean可以被Spring掃描到
  • 怎麼讓Bean進行自動裝配
  • 總結

Spring經過組件掃描和自動裝配實現自動化裝配Bean,經過自動化裝配,能最大程度的減小各類顯式配置。數組

Spring開啓組件掃描的方式

組件掃描默認是不開啓的,所以須要咱們手動去啓動。Spring開啓組件掃描有如下兩種方式。安全

經過Java配置類
  1. 基本示例
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 {

}
  1. 定義組件掃描的基礎包微信

    若是咱們但願把配置類與核心代碼類放在不一樣的包中,這時候默認的加載地址對咱們就沒有意義了。這時候咱們能夠自定義組件掃描的基礎包。有如下兩種方式: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 {
    
    }

    可是以上方式有個明顯的缺陷,其是類型不安全的,若是某次重構代碼的時候,包名可能會改變,那麼這裏設置的valuebasePackages就須要改變了。若是你設置了多個多個配置類,想一想,多麼可怕?那麼咱們來個更實用的。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代替了valuebasePackages屬性。程序在解析的時候,會以BasePackageLocation類所在的路徑做爲基礎包路徑。

    咱們通常採用第二種方式進行配置,一般的作法是,在須要掃描的包下創建一個空接口,什麼都不寫。經過標記接口的形式找到基礎包,同時因爲是空接口,你在重構時能夠不加理會,這種方式是對重構友好的。

經過XML文件配置

經過在Spring的xml配置文件中添加以下元素:

<context:component-scan base-package="com.lurker.springaction.yjiang.autowire">

經過這種方式可以取得跟Java配置相同的效果。同時,這種方式也支持同時配置多個包。

如何讓Bean可以被Spring掃描到

開啓了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的做用,他們分別是:

  • @Controller:註解Controller層
  • @Service:註解Service層
  • @Repository:註解DAO層

這三個註解繼承自@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 {
}

如何讓Bean實現自動裝配

萬事俱備,只欠東風。Spring已經掃描到了進行標註後的Bean,並已經將他們放入容器中了,怎麼把Bean裝配到須要的地方呢?

Spring經過@Autowired註解來實現Bean的自動裝配。@Autowired註解能夠用在類的任何地方。可是,請注意,若是在裝配過程當中,若是某個須要的Bean不存在,那麼Spring會拋出一個異常。若是這個欠缺的Bean不是那麼重要,那麼你能夠嘗試經過required設置爲false來忽略掉它不存在的事實。

  1. 註解在構造方法上
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;
    }
}
  1. 註解在setter方法上
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;
    }
}
  1. 註解在屬性上
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;
    }
}
  1. 註解在任意方法上
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());
    }

}
  1. 忽視某個Bean不存在的事實
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的裝配。一塊兒期待吧!!!

生命不止,學習不休,加油!!!

相關文章
相關標籤/搜索