《Spring實戰》-第二章:Bean的裝配(2)-JavaConfig顯式裝配

慢慢來比較快,虛心學技術

前言:創建應用對象之間協作關係的行爲通常稱爲裝配( wiring ),這也是依賴注入( DI )的本質

Spring提供三種Bean裝配機制:

  1. 在 XML 中進行顯式配置。
  2. 在 Java 中進行顯式配置
  3. 隱式的 bean 發現機制和自動裝配

一、爲什麼使用JavaConfig顯式配置?

相比於XML顯式配置,javaConfig顯然是更好的方案

  • Ⅰ.本就是java代碼,便於重構管理
  • Ⅱ.類型安全,更爲強大
  • Ⅲ.配置方便,簡潔

二、怎麼配置?

java顯式配置:類似於XML配置模式,顯式配置每個Bean的名稱

在實現之前我們需要了解一下幾個基本註解:

@Autowired :標記於屬性,方法等,自動裝配的關鍵註解,依賴注入的表現,該註解可以自動尋找並從Spring容器中提取使用該註解的bean並注入到對應的屬性中去

@Bean:該註解用於配置類中,註明某方法是裝配方法,方法名就是裝配的Bean名稱(javaConfig顯式配置的核心註解)

@Configuration :標記於配置類,標明當前類是一個配置類

① 與上一篇文章一樣,基礎類代碼不變。

public class CDBean {

    /**
     * 定義CD名
     */
    private String title="The World!";

    /**
     * 定義CD作者
     */
    private String author="Mr.D";

}

② CDPlayerImp類增加CDPlayerImpl(CDBean cdBean)構造方法,方便後續注入

public class CDPlayerImpl implements CDPlayer {

    private CDBean cdBean;

    public CDPlayerImpl() {
        super();
    }

    public CDPlayerImpl(CDBean cdBean) {
        super();
        this.cdBean = cdBean;
    }

    @Override
    public void playCD() {
        System.out.println("正在播放:"+cdBean.getTitle()+" by "+cdBean.getAuthor());
    }
}

③ CDConfig類更改配置方式,顯式配置每一個類

@Configuration//標明配置
public class CDConfig {

    @Bean
    public CDBean cdBean(){
        return new CDBean();
    }

    @Bean
    public CDPlayer cdPlayer(){
        return new CDPlayerImpl(cdBean());
    }
}

④註解測試,將配置類指向CDConfig2

此處使用Spring提供的測試類SpringJUnit4ClassRunner幫助測試,以便在測試開始的時候自動創建 Spring 的應用上下文,而@ContextConfiguration可以指定創建上下文的加載方式以及配置的位置等

@RunWith(SpringJUnit4ClassRunner.class)//使用Spring提供的測試包進行測試,主要幫助實現bean的裝載環境
@ContextConfiguration(loader = AnnotationConfigContextLoader.class,classes = {CDConfig2.class})//配置類指向CDConfig2
public class AppTest 
{
    //使用註解自動注入
    @Autowired
    private CDPlayer cdPlayer;

    /**
     * Rigorous Test :-)
     */
    @Test
    public void play()
    {
        this.cdPlayer.playCD();
    }
}

⑤測試結果:

正在播放:The World! by Mr.D

⑥Spring提供另一種測試方式,通過Spring應用上下文AnnotationConfigApplicationContext上下文實現進行測試

public class App 
{
    public static void main(String[] args) {

        /**
         * 之所以要指定配置類,相當於,寫了xml文件也一樣需要指定xml文件位置一樣,spring並不能自動開啓註解並讀取配置
         */
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(CDConfig2.class);

        //獲取應用上下文中的所有Bean名稱
        String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
        for (String className : beanDefinitionNames){
            System.out.println(className);
        }

        CDPlayer cdPlayer = applicationContext.getBean(CDPlayer.class);

        cdPlayer.playCD();
    }
}

⑦ 測試結果

org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
CDConfig2
cdBean
cdPlayer
正在播放:The World! by Mr.D

注:

Ⅰ、@Bean註解可以爲Bean另起ID,源碼中有屬性如下,name屬性是一個用{}包圍起來字符串數組,表明可以定義多個id:

public @interface Bean {

   /**
    * Alias for {@link #name}.
    * <p>Intended to be used when no other attributes are needed, for example:
    * {@code @Bean("customBeanName")}.
    * @since 4.3.3
    * @see #name
    */
   @AliasFor("name")
   String[] value() default {};

   /**
    * The name of this bean, or if several names, a primary bean name plus aliases.
    * <p>If left unspecified, the name of the bean is the name of the annotated method.
    * If specified, the method name is ignored.
    * <p>The bean name and aliases may also be configured via the {@link #value}
    * attribute if no other attributes are declared.
    * @see #value
    */
   @AliasFor("value")
   String[] name() default {};
}

由上述源碼可做如下更改:

@Configuration
public class CDConfig2 {

    @Bean(name = {"CDBEAN"})
    public CDBean cdBean(){
        return new CDBean();
    }

    @Bean
    public CDPlayer cdPlayer(){
        return new CDPlayerImpl(cdBean());
    }
}

執行⑥測試結果如下:CDBean的裝配ID已成功更改

org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
CDConfig2
CDBEAN
cdPlayer
正在播放:The World! by Mr.D

Ⅱ、@Bean註解的使用,內部注入不只是能在構造方法內,還可以在setter和普通方法等注入

@Configuration
public class CDConfig2 {

    @Bean(name = {"CDBEAN"})
    public CDBean cdBean(){
        return new CDBean();
    }

    @Bean
    public CDPlayer cdPlayer(){
        CDPlayer cdPlayer = new CDPlayerImpl();
        cdPlayer.setCDBean(cdBean());//在setter方法中注入
    }
}

總結

1、JavaConfig顯式配置相對於XML顯式配置來說,具有配置簡單,維護方便的優點

2、JavaConfig顯式配置主要依賴於@Bean註解和@Configuration兩個註解實現,其中@Configuration註解標明當前類爲配置類,而@Bean使用在配置類中的方法內,定義一個裝配類名爲方法名的Bean

3、Spring使用@Autowired進行依賴注入

4、Spring中我們可以通過兩種方式方便的對javaConfig顯式配置進行測試,一種是結合SpringJUnit4ClassRunner模擬裝配環境進行測試,一種是使用應用上下文AnnotationConfigApplicationContext進行測試

參考文檔

【1】《Spring 實戰(第 4 版)》·Craig Walls

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