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

慢慢來比較快诀姚,虛心學(xué)技術(shù)

前言:創(chuàng)建應(yīng)用對象之間協(xié)作關(guān)系的行為通常稱為裝配( wiring )响牛,這也是依賴注入( DI )的本質(zhì)

Spring提供三種Bean裝配機(jī)制:

  1. 在 XML 中進(jìn)行顯式配置。
  2. 在 Java 中進(jìn)行顯式配置
  3. 隱式的 bean 發(fā)現(xiàn)機(jī)制和自動裝配

一、為什么使用JavaConfig顯式配置呀打?

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

  • Ⅰ.本就是java代碼,便于重構(gòu)管理
  • Ⅱ.類型安全贬丛,更為強(qiáng)大
  • Ⅲ.配置方便撩银,簡潔

二、怎么配置瘫寝?

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

在實(shí)現(xiàn)之前我們需要了解一下幾個基本注解:

@Autowired :標(biāo)記于屬性,方法等焕阿,自動裝配的關(guān)鍵注解咪啡,依賴注入的表現(xiàn),該注解可以自動尋找并從Spring容器中提取使用該注解的bean并注入到對應(yīng)的屬性中去

@Bean:該注解用于配置類中暮屡,注明某方法是裝配方法撤摸,方法名就是裝配的Bean名稱(javaConfig顯式配置的核心注解)

@Configuration :標(biāo)記于配置類,標(biāo)明當(dāng)前類是一個配置類

① 與上一篇文章一樣褒纲,基礎(chǔ)類代碼不變准夷。

public class CDBean {

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

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

}

② CDPlayerImp類增加CDPlayerImpl(CDBean cdBean)構(gòu)造方法,方便后續(xù)注入

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//標(biāo)明配置
public class CDConfig {

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

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

④注解測試衫嵌,將配置類指向CDConfig2

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

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

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

⑤測試結(jié)果:

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

⑥Spring提供另一種測試方式,通過Spring應(yīng)用上下文AnnotationConfigApplicationContext上下文實(shí)現(xiàn)進(jìn)行測試

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

        /**
         * 之所以要指定配置類唇兑,相當(dāng)于酒朵,寫了xml文件也一樣需要指定xml文件位置一樣,spring并不能自動開啟注解并讀取配置
         */
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(CDConfig2.class);

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

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

        cdPlayer.playCD();
    }
}

⑦ 測試結(jié)果

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屬性是一個用{}包圍起來字符串?dāng)?shù)組留夜,表明可以定義多個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());
    }
}

執(zhí)行⑥測試結(jié)果如下: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注解的使用,內(nèi)部注入不只是能在構(gòu)造方法內(nèi)碍粥,還可以在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方法中注入
    }
}

總結(jié)

1慰枕、JavaConfig顯式配置相對于XML顯式配置來說,具有配置簡單即纲,維護(hù)方便的優(yōu)點(diǎn)

2、JavaConfig顯式配置主要依賴于@Bean注解和@Configuration兩個注解實(shí)現(xiàn)博肋,其中@Configuration注解標(biāo)明當(dāng)前類為配置類低斋,而@Bean使用在配置類中的方法內(nèi)蜂厅,定義一個裝配類名為方法名的Bean

3、Spring使用@Autowired進(jìn)行依賴注入

4膊畴、Spring中我們可以通過兩種方式方便的對javaConfig顯式配置進(jìn)行測試掘猿,一種是結(jié)合SpringJUnit4ClassRunner模擬裝配環(huán)境進(jìn)行測試,一種是使用應(yīng)用上下文AnnotationConfigApplicationContext進(jìn)行測試

參考文檔

【1】《Spring 實(shí)戰(zhàn)(第 4 版)》·Craig Walls

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末唇跨,一起剝皮案震驚了整個濱河市稠通,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌买猖,老刑警劉巖改橘,帶你破解...
    沈念sama閱讀 211,817評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異玉控,居然都是意外死亡飞主,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,329評論 3 385
  • 文/潘曉璐 我一進(jìn)店門高诺,熙熙樓的掌柜王于貴愁眉苦臉地迎上來碌识,“玉大人,你說我怎么就攤上這事虱而》げ停” “怎么了?”我有些...
    開封第一講書人閱讀 157,354評論 0 348
  • 文/不壞的土叔 我叫張陵牡拇,是天一觀的道長魁瞪。 經(jīng)常有香客問我,道長诅迷,這世上最難降的妖魔是什么佩番? 我笑而不...
    開封第一講書人閱讀 56,498評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮罢杉,結(jié)果婚禮上趟畏,老公的妹妹穿的比我還像新娘。我一直安慰自己滩租,他們只是感情好赋秀,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,600評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著律想,像睡著了一般猎莲。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上技即,一...
    開封第一講書人閱讀 49,829評論 1 290
  • 那天著洼,我揣著相機(jī)與錄音,去河邊找鬼。 笑死身笤,一個胖子當(dāng)著我的面吹牛豹悬,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播液荸,決...
    沈念sama閱讀 38,979評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼瞻佛,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了娇钱?” 一聲冷哼從身側(cè)響起伤柄,我...
    開封第一講書人閱讀 37,722評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎文搂,沒想到半個月后适刀,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,189評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡细疚,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,519評論 2 327
  • 正文 我和宋清朗相戀三年蔗彤,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片疯兼。...
    茶點(diǎn)故事閱讀 38,654評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡然遏,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出吧彪,到底是詐尸還是另有隱情待侵,我是刑警寧澤,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布姨裸,位于F島的核電站秧倾,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏傀缩。R本人自食惡果不足惜那先,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,940評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望赡艰。 院中可真熱鬧售淡,春花似錦、人聲如沸慷垮。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,762評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽料身。三九已至汤纸,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間芹血,已是汗流浹背贮泞。 一陣腳步聲響...
    開封第一講書人閱讀 31,993評論 1 266
  • 我被黑心中介騙來泰國打工楞慈, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人隙畜。 一個月前我還...
    沈念sama閱讀 46,382評論 2 360
  • 正文 我出身青樓抖部,卻偏偏與公主長得像,于是被迫代替她去往敵國和親议惰。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,543評論 2 349

推薦閱讀更多精彩內(nèi)容