裝配Bean

建立應用對象之間協做關係的行爲一般被稱爲裝配(wiring),這是依賴注入(DI)的本質。當描述bean如何進行裝配時,Spring具備很是大的靈活性,它提供了三種主要的裝配機制:java

  • 在XML中進行顯式配置;
  • 在Java中進行顯式配置;
  • 隱式的bean發現機制和自動裝配

前兩種都是屬於顯式的配置,最後一種是就是所謂的自動裝配了。其實選擇哪種方案沒有什麼絕對的,更多的時候是根據本身的喜愛。Spring的配置風格是能夠相互搭配的,因此能夠選擇使用XML裝配一些bean,使用Spring基於Java的配置(JavaConfig)來裝配另外一些bean,而將剩餘的bean讓Spring自動發現,這種混合方式也是能夠的。spring

做者建議儘量的使用自動裝配的機制。顯式配置越少越好。當你必須顯式配置bean的時候(好比,有些代碼不是由你進行維護或是Jar包中的類,而當你須要爲這些代碼配置bean的時候),推薦使用類型安全而且比XML更增強大的JavaConfig,最後只有當你想使用便利的XML命名空間,而且在JavaConfig中沒有相同的實現時,才應該使用XML。(而我以前一直使用的是自動裝配,接下來就是XML的方式,對於JavaConfig的方式只是知道,而沒有使用過,緣由在於硬編碼這一點,可是由於XML沒有類型檢查,因此做者更多的是從後期重構的角度出發,使用JavaConfig更爲安全,在之後的項目中也能夠嘗試使用JavaConfig的方式)windows

自動裝配bean

Spring從兩個角度實現自動裝配:數組

  • 組件掃描(component scaning):Spring會自動發現上下文所建立的bean
  • 自動注入(autowiring):Spring自動知足bean之間的依賴

將主鍵掃描與自動注入結合,能夠把顯式配置下降到最少。安全

建立bean

咱們使用@Component註解代表一個類做爲組件類,並告知Spring要爲這個類建立bean。app

爲組件掃描的bean命名

Spring應用上下文中的全部bean都會給一個ID,若是沒有明確爲bean指明ID,Spring會根據類名爲其指定一個ID,也就是將類名首字母小寫。想爲這個bean設置不一樣的ID,你所要說的就是將指望的ID做爲值傳遞給@Component註解:dom

@Component("cdplayer")
public class CdPlayer implements MediaPlayer {

還有另外一種爲bean命名的方式,這個方式不使用@Component註解,而是使用Java依賴注入規範中所提供的@Named註解來爲bean設置ID:工具

import javax.inject.Named;

@Named("cdplayer")
public class CdPlayer implements MediaPlayer

Spring支持將@Named做爲@Component註解的替代方案,在大多數場景中,他們能夠互相替換,可是我更加喜歡使用@Component註解。開發工具

組件掃描默認是不開啓的。咱們還須要顯式配置一下Spring,從而命令它尋找帶有@Component註解的類,看來自動裝配仍是須要一點顯式配置的。咱們先使用JavaConfig的方式開啓組件掃描:測試

@Configuration註解是用在JavaConfig方式中,用於代表該類是一個配置類,使用JavaConfig的方式不要忘記在配置類中加這個註解。

而ComponentScan註解纔是真正啓用組件掃描。

設置組件掃描的基礎包

若是沒有其餘配置的話,@ComponentScan默認會掃描與配置類相同的包,並將配置類所在的包做爲基礎包(base package)來掃描組件,可是,若是你想掃描不一樣的包,或者掃描多個基礎包,須要在@ComponentScan的value屬性中指明包的名稱:

@Configuration
@ComponentScan("cn.lynu")
public class CDPlayerConfig {

若是想要清晰地代表你所須要的基礎包,那麼能夠經過basePackages屬性進行配置:

@Configuration
@ComponentScan(basePackages="cn.lynu")
public class CDPlayerConfig {

basePackages屬性使用的是複數,這意味着能夠配置多個基礎包,配置多個基礎包,設置一個數組便可:

@Configuration
@ComponentScan(basePackages= {"cn.lynu","cn.lynu2"})
public class CDPlayerConfig {

在上面的例子中,咱們設置基礎包都是用String類型表示的,這是類型不安全的,若是後期重構代碼,所指定的基礎包就有可能出現錯誤。因此@ComponentScan提供了另外一種方法,將類或接口做爲組件掃描的基礎包,使用的是basePackageClasses設置的基礎類:

@Configuration
@ComponentScan(basePackageClasses= {CdPlayer.class,DvDPlayer.class})
public class CDPlayerConfig {

能夠考慮在包中建立一個用於進行掃描的空標記接口。經過標記接口的方式,依然可以保持對重構友好的接口引用,可是能夠避免引用任何實際的應用程序代碼。

若是更傾向於使用XML開啓組件掃描的話,使用Spring context命名空間的<context:component-scan>元素:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">


    <context:component-scan base-package="cn.lynu"></context:component-scan>


</beans>

<context:component-scan>元素有與@ComponentScan註解相對應屬性和子元素。

經過註解實現自動裝配

要使用自動裝配,能夠藉助Spring的@AutoWired註解,能夠在構造器上添加@AutoWired註解,這代表當Spring建立bean的時候,會使用這個構造器進行實例化而且會傳入所需的類型的bean:

@Autowired註解不只可以用在構造器上,還能用在屬性的setter方法上:

    @Autowired
    public void setCompactDisc(CompactDisc cd) {
        this.cd = cd;
    }

實際上,Setter方法並無什麼特殊之處,@AutoWired能夠用在類的任何方法上。例如:

 @Autowired
    public void insertDisc(CompactDisc cd) {
        this.cd = cd;
    }

無論是構造器,Setter方法仍是其餘方法,Spring都會嘗試知足方法參數上聲明的依賴,假若有且只有一個bean配置的話,那麼這個bean就會被裝配進來。若是沒有配備的bean,那麼在應用上下文建立的時候,Spring就會拋出一個異常。爲了不這個異常的出現,能夠將@Autowired的required屬性設置爲false:

@Autowired(required=false)
    public CdPlayer(CompactDisc cd) {
        this.cd = cd;
    }

將required屬性設置爲false,若是沒有匹配的bean的話,Spring就會讓這個bean處於未裝配的狀態,可是,正由於此,須要很謹慎地對待,由於若是沒有非空檢查,就會出現NullPointerException。

若是有多個bean被匹配上,Spring也會拋出一個異常,代表沒法明確指定要使用哪一個bean進行自動裝配。

@Autowirer是Spring特有的註解,若是不想使用,咱們也可使用Java依賴注入規範中的@Inject:

import javax.inject.Named;

@Named("cdplayer")
public class CdPlayer implements MediaPlayer{
        ...
        @Inject
        public CdPlayer(CompactDisc cd){
                 this.cd=cd;
    }
         
}        

測試自動裝配

package cn.lynu;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

import org.junit.Rule;
import org.junit.Test;
import org.junit.contrib.java.lang.system.SystemOutRule;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes=CDPlayerConfig.class)
public class CDPlayTest {
    
    @Rule
    public final SystemOutRule log = new SystemOutRule().enableLog();

    @Autowired
    private CompactDisc compactDisc;
    
    @Autowired
    private MediaPlayer player;
    
    @Test
    public void cdShouldnotBeNull() {
        assertNotNull(compactDisc);
    }
assertTrue(compactDisc==player.getCd());
    }
    
    @Test
    public void play() {
        player.play();
        //使用System.out.println的話,別忘了\r\n
        assertEquals("Playing Sgt. Pepper's Lonely Hearts Club Band by The Beatles\r\n", log.getLog());
    }
    
}

使用Spring的 SpringJUnit4ClassRunner (Spring-test.jar)以便測試開始的時候自動建立Spring上下文(而不是使用applicationContext的之子類,如ClassPathXmlApplicationContext或AnnotationConfigApplicationContext,FileSystemApplicationContext之類的顯式去建立應用上下文)。註解@ContextConfiguration會告訴Spring去哪裏加載配置。由於在代碼中使用了System.out.println()在控制檯打印東西,因此我使用了 SystemOutRule 對象來測試打印的內容時候正確,而不是經過人眼去看。SystemOutRule源於System Rules庫中的一個Junit規則,該規則能夠基於控制檯的輸出內容編寫斷言。值得注意的是,使用println輸出,在windows環境下須要使用「\r\n」來比對。

經過Java代碼裝配bean

儘管經過組件掃描和自動注入的方式實現Spring的自動化配置更爲推薦,可是有時候自動配置的方案行不通,好比須要將第三方庫中的組件裝配到你的應用中,咱們沒有辦法在它的類上添加@Component和@Autowired註解,這個時候就須要使用顯式配置。在進行顯式配置的時候,有兩種可選方案:Java和XML。咱們先來看看基於Java的配置。

其實咱們以前用的CDPlayerConfig類就是一個配置類(讓咱們先把CDPlayerConfig的@ComponentScan註解取消,這裏不是使用組件掃描),若是使用JavaConfig,一般會將這些配置類放在單獨的包中,使它們與其餘應用程序邏輯分離出來。建立JavaConfig配置類的關鍵在於使用@Configuration註解,這個註解代表當前類是一個配置類,該類包含Spring引用上下文如何建立bean的細節。

聲明簡單的bean

要在JavaConfig中聲明bean,咱們須要編寫一個方法,這個方法會建立所需類型的實例,而後給這個方法添加@Bean註解。

    @Bean
    public CompactDisc sgtPeppers() {
        return new SgtPeppers();
    }

@Bean註解會告訴Spring這個方法會返回一個對象,該對象要註冊爲Spring應用上下文的bean。默認狀況下,bean的id於帶有@Bean註解的方法名是同樣的。若是你想爲其設置成一個不一樣的名字的話,可使用name屬性:

 @Bean(name="disc")
    public CompactDisc sgtPeppers() {
        return new SgtPeppers();
    }

爲何說使用JavaConfig的方式比XML更爲強大,一方面是由於有類型檢查,另外一方面是由於在Javc類中能夠進行邏輯控制,咱們能夠控制建立的實例:

    @Bean
    public CompactDisc sgtPeppers() {
        int choise=(int)Math.floor(Math.random()*4);
        if(choise==0) {
            return new SgtPeppers();
        }else if(choise==1) {
            return new WhiteAlbum();
        }else if(choise==2) {
            return new HandDayNight();
        }else {
            return new Revolver();
        }
    }

藉助JavaConfig實現注入

在這裏咱們再也不使用@Autowired來進行注入,咱們的注入方式是這樣的:

@Bean
    public MediaPlayer cdPlayer() {
        return new CdPlayer(sgtPeppers());
    }

經過調用 sgtPeppers()方法實現,看起來,這種方式每次都會獲得有個新的 SgtPeppers 實例,由於每次調用都返回new的新的對象,可是咱們能夠比較這兩個 SgtPeppers 實例,發現它們居然是同一個實例。這是由於 sgtPeppers()方法上添加了@Bean註解,Spring會攔截全部對它的調用並確保返回的是Spring所建立的bean,也就是Spring在調用 sgtPeppers()方法時,容器本身建立的,因此,能夠這樣說,在默認狀況下,Spring中的bean都是單例的。

這裏這個調用的方式會出現歧義,咱們可使用更爲明確的方式:

@Bean
    public MediaPlayer cdPlayer(CompactDisc compactDisc) {
        return new CdPlayer(compactDisc);
    }

將所需的依賴類做爲方法的參數,當Spring調用 cdPlayer()建立bean的時候,依賴類就會自動裝配進方法中。這種方法也不會要求將 CompactDisc 聲明在同一個配置類中,更沒有要求CompactDisc必須經過JavcConfig的方式聲明,咱們徹底可使用自動掃描或XML方式裝配這個bean,無論經過什麼方式建立的CompactDisc ,Spring都會將其傳入配置方法中。

上面,咱們一直使用構造器建立的bean(new出來的),咱們也可使用setter方法注入:

@Bean
    public MediaPlayer cdPlayer(CompactDisc compactDisc) {
        CdPlayer player=new CdPlayer();
                player.setCompactDisc(compactDisc);
                 return player;
    }

經過使用XML裝配bean

在Spring剛出來的時候,XML是其主要的配置方式,但如今有了強大的自動化配置和基於Java的配置,做者不在建議使用XML做爲第一選擇,可是仍是存在大量的基於XML的Spring配置,而其我也是比較多個在使用XML方式,因此仍是須要理解這種方式。

在JavaConfig中,咱們配置須要使用一個被@Configuration修飾的類,而在XML中這意味着建立一個XML文件,而且要以<beans>元素爲根元素。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">

</beans>

聲明一個簡單的bean

使用<bean>標籤相似於javaConfig中的@Bean註解,咱們能夠這樣聲明:

<bean class="cn.lynu.SgtPeppers"/>

這個bean須要經過class屬性指明是哪一個類,使用的是全限定名。若是沒有給這個bean指明ID,就如上面這個,會默認有一個Bean的ID,在這裏是「cn.lynu.Sgtpeppers#0」,其中,「#0」是一個計數的形式,若是聲明瞭另外一個Sgtpeppers也沒有給ID,那麼它自動獲得的ID就會是"cn.lynu.Sgtpeppers#1".

在大可能是狀況下,咱們都會給bean一個咱們自定義的ID,由於若是後面須要引用它,那麼自動生成的名字就沒太大用處了。一般使用id屬性,爲每個bean設置一個你本身選擇的名字:

<bean id="compactDisc" class="cn.lynu.SgtPeppers"/>

當Spring發現<bean>這個元素時,它會調用 SgtPeppers 的默認構造器來建立bean。相比較於JavaConfig,XML建立bean的方式更爲被動,它不如JavaConfig那樣,咱們能夠經過邏輯判斷來選擇性建立bean。並且在<bean>標籤中使用的class值是以字符串的方式設置的,若是重命名類,而忘記修改XML就會出錯,XML沒有在編譯期進行類型檢查的能力(還好的是如今的Spring開發工具,例如Eclipse中的插件,或是STS都會去檢查XML中的元素與屬性)。

經過構造器注入依賴

在XML中使用DI,經過使用構造器的方式基本上有兩種方案可供選擇:

  • <constructor-arg>元素
  • 使用Spring3.0以後所引入的c命名空間

構造器輸入bean的引用

可使用<constructor-arg>元素的ref屬性來引用其餘bean:

<bean id="cdPlayer" class="cn.lynu.CdPlayer">
        <constructor-arg ref="compactDisc"/>
</bean>

Spring會將Id等於 compactDisc 的bean引用傳遞給 CdPlayer 的參數爲CompactDisc的構造器進行初始化。

做爲替代方法,也可使用Spring的c命名空間,它是在XML更爲簡潔的描述構造器參數的方法,要使用它,必須先引入其XML約束:

xmlns:c="http://www.springframework.org/schema/c"

聲明以後,咱們就可使用它聲明構造器參數了:

<bean id="cdPlayer" class="cn.lynu.CdPlayer" c:cd-ref="cdPlayer" />

它是由命名規範的,以c:打頭,也就是命名空間的前綴,接下來是構造器的參數名,在此以後使用的是"-ref",這是一個命名的約定,它會告訴Spring正在裝配的是一個bean的引用,而不是字面量。由於使用的是參數名,參數名頗有可能在以後被修改,因此也可使用參數在參數列表中的位置表示:

<bean id="cdPlayer" class="cn.lynu.CdPlayer" c:_0-ref="cdPlayer" />

由於XML不容許將數字做爲屬性的第一個參數,因此添加一個下劃線做爲前綴,多個參數以此類推便可。

由於這裏只有一個參數,因此咱們可使用更爲簡單的方式:

<bean id="cdPlayer" class="cn.lynu.CdPlayer" c:_-ref="cdPlayer" />

這裏沒有使用參數名或參數索引,而是利用一個下劃線,注意:它只適用於一個參數的狀況。

將字面量注入到構造器

咱們使用ref將bean的引用傳遞給構造器,但有的時候,咱們可能只是須要用一個字符串來配置對象。咱們先來使用<constructor-arg>元素來進行構造器注入,可是此次不是用ref,而是value屬性,經過該屬性代表給定的值要以字面量的方式注入到構造器。

<bean id="cdPlayer" class="cn.lynu.CdPlayer">
    <constructor-arg value="123"/>
    <constructor-arg value="abc"/>
</bean>

若是使用c命名空間,又該如何使用呢?

<bean id="cdPlayer" class="cn.lynu.CdPlayer" c:title="123" c:artist="abc" />

仍舊是c:參數名的方式,只不過是參數名後去掉了「-ref」後綴,固然,咱們也可使用參數索引的方式裝配字面量:

<bean id="cdPlayer" class="cn.lynu.CdPlayer" c:_0="123" c:_1="abc" />

由於這裏涉及到多個參數(兩個或兩個以上)的狀況,因此這裏不能再使用一個下劃線的方式,除非是隻有一個構造器參數。

在裝配bean引用和字面量方面,<constructor-arg>元素與c命名空間做用是相同的,可是,在裝配集合類型的時候,就不同了。

裝配集合

先來改改構造器,添加一個集合做爲參數:

public CdPlayer(List<String> tracks) {
        this.tracks = tracks;
    }

當咱們不知道傳怎樣的集合做爲參數的時候,可使用<null/>標籤,將一個空值進行傳遞:

<bean id="cdPlayer" class="cn.lynu.CdPlayer">
    <constructor-arg><null/></constructor-arg>
</bean>

固然,這不是很好的方案,由於雖然在注入期能夠正常執行,可是運行的時候會出現NullPointerException異常。

咱們使用<list>標籤表示一個列表:

<bean id="cdPlayer" class="cn.lynu.CdPlayer">
    <constructor-arg>
        <list>
            <value>1</value>
            <value>2</value>
            <value>3</value>
        </list>
    </constructor-arg>

<value>代表這個列表的元素都是字面量,固然,咱們也可使用<ref>元素,實現bean引用列表的裝配。

但參數的類型是java.util.List的時候,使用<list>元素是合情合理的,儘管如此,咱們也能夠按照一樣的方式使用<set>元素:

<bean id="cdPlayer" class="cn.lynu.CdPlayer">
    <constructor-arg>
        <set>
            <value>1</value>
            <value>2</value>
            <value>3</value>
        </set>
    </constructor-arg>
</bean>

<set>和<list>元素區別不大,其中最重要的是當以String須要裝配進集合,所使用的是java.util.Set仍是java.util.List,若是是Set的話,全部重複的值會被忽略,存放的順序也不會獲得保證。不過不管在哪一種狀況下,使用<set>或<list>均可以用來裝配List或Set甚至數組。

屬性注入

咱們注入的方式除了使用構造器,咱們也可使用setter方式,<property>元素爲屬性的setter方法提供與<constructor-arg>元素功能同樣:

<bean id="cdPlayer" class="cn.lynu.CdPlayer">
    <property name="cd" ref="compactDisc"></property>
</bean>

ref屬性引用Id爲 compactDisc 的bean,name屬性指明須要注入到參數名爲cd的屬性中(經過setCd()方法)。引用的注入使用ref,字面量使用value屬性

Spring還提供了更爲簡潔的p命名空間,做爲<property>屬性的替代方案。與c命名空間相似,須要先導入p的約束:

xmlns:p="http://www.springframework.org/schema/p"

咱們使用p命名空間進行裝配:

<bean id="cdPlayer" class="cn.lynu.CdPlayer" p:cd-ref="compactDisc"></bean>

命名規範與c一致,p:屬性名+"-ref",-ref作爲引用的注入,去掉-ref表示裝配字面量。

咱們以前說過使用命名空間比標籤的缺點就是不能直接注入集合,可是Spring提供了util命名空間用於解決這個問題,仍是先引入util約束:

xmlns:util="http://www.springframework.org/schema/util"

util命名空間所提供的功能之一就是<util:list>元素,它會建立一個列表的bean

<util:list id="trackList">
    <value>11111</value>
    <value>22222</value>
    <value>33333</value>
</util:list>

這個時候c/p命名空間才能夠注入集合:

<bean id="cdPlayer" class="cn.lynu.CdPlayer" p:tracks-ref="trackList"></bean>

固然 <util:list>元素只是util命名空間中的成員之一。

混合配置

在Spring中自動裝配,JavaConfig,XML的方式都不是互斥的(由於裝配並不在於這個bean來自於哪裏),咱們能夠將它們混合在一塊兒。實際上使用自動裝配仍是須要一點顯式配置來開啓組件掃描和自動注入。

那麼在顯式配置(未使用自動裝配)中,如何在XML配置和Java配置中引入對方的bean。

在JavaConfig中引用XML配置

在引入XML方式以前咱們先來講一下如何將其餘的JavaConfig配置類引入到本配置類中。使用的正是@Import註解,

@Configuration
@Import(CDConfig.class) public class CDPlayerConfig {

或者採用一個更好的方法,就是否是在某一個配置類中引入其餘配置類,而是建立一個更高級別的配置類,在這個配置那種使用@Import將多個配置類組合在一塊兒:

@Configuration
@Import({CDPlayerConfig.class,CDConfig.class})
public class SoundSystemConfig {

好了,回到正題,如何在JavaConfig中引入XML配置,答案就是@ImportResource註解,來看看如何引入一個位於根類路徑下的名爲applicationContext.xml的配置文件:

@Configuration
@Import(CDPlayerConfig.class)
@ImportResource("classpath:applicationContext.xml")
public class SoundSystemConfig {

Ok,不管是在JavaConfig仍是在XML配置的bean都會被加載到Spring容器中。

在XML中引入JavaConfig

咱們仍是想來看看如何拆分XML的,使用的是<import>標籤:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd">

    <import resource="cd-config.xml"/>

</bean>

那麼咱們可不可使用這個標籤導入JavaConfig類,事實上並不能夠,<import>標籤只能導入XML文件,想要導入Java配置,使用的是咱們很熟悉的<bean>標籤:

<bean class="cn.lynu.CDConfig" />

相似的,咱們能夠採用一個更高級的配置文件,這個文件不聲明任何bean,只是負責將兩個或更多個配置組合起來。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:c="http://www.springframework.org/schema/c"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:util="http://www.springframework.org/schema/util"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd">

    <import resource="cd-config.xml"/>
    <bean class="cn.lynu.CDConfig" />

</bean>

無論是JavaConfig仍是XML進行裝配,都建議在用一個更高層次的配置(就如上面這樣),這個配置能夠將兩個或多個javaConfig或XML文件組合起來。也能夠在這個配置中開啓組件掃描(經過<context:component-scan>或@ComponentScan)。

相關文章
相關標籤/搜索