天天看點

Spring In Action學習筆記:Bean的簡單裝配

裝配Bean

Spring提供了三種主要的Bean裝配機制

- 在xml中進行顯示配置(便利的命名空間)

- 在Java中進行顯示配置(相對于xml是類型安全的)

- 隐式的bean發現機制和自動裝配

自動化裝配bean

Spring從兩個角度來實作自動化裝配

- 元件掃描 : Spring會自動發現應用上下文中所建立的bean

- 自動裝配 : Spring自動滿足bean之間的依賴

建立可被發現的bean

package soundsystem;
public interface CompactDisc{

    void play();
}

---------------------
@Compent //表明該類作為元件類并告知Spring為這類建立bean
public class SgtPeppers implements CompactDisc{

    private String title = "Sgt.Pepper's Lonely Hearts Club Band";

    private String artist = "The Beatles";

    public void play(){
        System.out.println("Playing" + title + "by" + artist);
    }
}

--------------------------------
元件掃描預設是不啟用的 需要@ComponentScan注解 或在xml中配置

package soundsystem;

@Configuration
@ComponentScan(basePackages={"...."})//basePackages指定要掃描的包,不指定的話預設為本類所在包
public class CDPlayerConfig{

}
然後通過AnnotationConfigApplicationCotext加載CDPlayerConfig.class 即可

xml啟動
...
<beans ....>
    <context:component-scan base-package="" />
    ....
</beans>

           

為元件掃描的bean命名

@Component注解可給bean設定類似xml中的ID

@Component("lonelyHeartsClub")
public classSgtPeppers{

}
不指定ID會預設為類名的第一個字母變為小寫作為ID
還有一種bean的命名方式 @Named("")
           

通過為bean添加注解實作自動裝配

自動裝配是讓Spring自動滿足bean依賴的一種方法 可以借助@Autowired注解
@Component
public class CDPlayer{

    private CompactDisc cd;

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

}

@Autowired注解不僅能用在構造器上,還能用在屬性的setter方法上 甚至用在類的任何方法上,因為setter方法并沒有什麼特别的
@Autowired(required=false)required屬性為false時 當自動裝配沒有比對的bean時 這個bean處于未裝配狀态(容易出現NUllPointerException)
也可以用@Inject
           

通過Java代碼裝配bean

優點是類型安全,重構友好

JavaConfig類的關鍵在于@Configuration 注解,以及@Bean注解

在JavaConfig中聲明bean要編寫一個方法建立所需類型的執行個體,并添加@Bean注解

@Configuration
public class CDPlayerConfig{

    @Bean //可通過name屬性指定不同名字
    public CompactDisc sgtPeppers(){

        return new SgtPeppers();
    }

    @Bean
    public CDPlayer cdPlayer(){

        return new CDPlayer(sgtPeppers());//引用建立bean的方法注入

    }

}

Spring會攔截所有對添加了@Bean注解的方法的調用,并確定直接傳回該方法所建立的bean

比如

     @Bean
    public CDPlayer cdPlayer(){

        return new CDPlayer(sgtPeppers());//引用建立bean的方法注入

    }

     @Bean
    public CDPlayer anotherCDPlayer(){

        return new CDPlayer(sgtPeppers());//引用建立bean的方法注入

    }

anotherCDPlayer 和之前的cdPlayer bean 完全一樣
           

通過xml裝配bean

簡單聲明

<bean id="compactDisc" class="soundsystem.SgtPeppers" />
           

不明确指定ID時 會預設根據全限定類名命名

如”soundsystem.SgtPeppers#0” #0表示計數,用來區分相同類型的其他bean

當Spring發現這個元素時,他将會調用SgtPeppers的預設構造器來建立bean

借助構造器初始化bean

  • 元素
  • 使用c命名空間

c命名空間聲明

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

    <bean id="cdPlayer" class="soundsystem.CDPlayer">
        <constructor-arg ref="compactDisc" />
    </bean>

    等價于

    <bean id="cdPlayer" class="soundsystem.CDPlayer"
        c:cd-ref="compactDisc";
    >

    </bean>

cd 表示構造器參數名 -ref表示要注入bean引用,也可以用參數的順序來表示 如 c:_-ref  隻有一個參數時還可以c:_-ref

将一個ID為compactDisc的bean引用傳遞到CDPlayer的構造器中
           

将字面量注入到構造器

當構造器為
public BlankDisc(String title,String artist){
    this.title = title;
    this.artist = artist;

}


<bean id=".." class="..">
    <constructor-arg value="Sgt.Pepper's.."/>
    <constructor-arg value="The Beatles" />

c命名空間

<bean id=".." class=".."
    c:_0=".."
    c:_1=".." />
           
裝配集合

裝配集合是可以但C命名空間做不到的

當構造器為
public BlankDisc(String title,String artist,List<String> tracks){
    this.title = title;
    this.artist = artist;
    this.tracks = tracks;
}

bean id=".." class="..">
    <constructor-arg value="Sgt.Pepper's.."/>
    <constructor-arg value="The Beatles" />
    <constructor-arg>
        <list>
            <value>Sgt.Pepper...</value>
            <value>....</value>
            ...
        </list>
    </constructor-arg>

如果list中是其他bean的引用的話

bean id=".." class="..">
    <constructor-arg value="Sgt.Pepper's.."/>
    <constructor-arg value="The Beatles" />
    <constructor-arg>
        <list>
            <ref bean="beanid" />

            ...
        </list>
    </constructor-arg>


也可以按同樣的方式使用<set>
           
屬性注入
public class CDPlayer{

    private CompactDisc cd;

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

}


<bean id = "cdPlayer" class="...">
    <property name="compactDisc" ref="compactDisc" />
</bean>

<property>元素為屬性的set方法提供的功能與<constructor-arg>為構造器提供的功能一樣

<property>可用p命名空間代替

<bean id = "cdPlayer" class="..."
    p:cd-ref="">
</bean>

cd 是屬性的名字

屬性也可以注入字面量 以及list

<bean id = "cdPlayer" class="..."
    p:title="Sgt.Pepper...."
    p:artist="....">

</bean>

<bean id = "cdPlayer" class="...">
    <property name="title" value="Sgt.Pepper...." />
    <property name="artist" value="..."/>
    <property name="tracks">
        <list>
            <value>....</value>
            ...
        </list>
    </property>
</bean>

</bean>


           

util命名空間

功能之一 提供元素,他會建立一個清單的bean,供引用

<util:list id="trackList">
    <value>Sgt.....</value>
    .....
</util:lsit>

<bean id="..." class="..."
    p:title = "..."
    p:artist = "..."
    p:tracks-ref="trackList" />
           

導入和混合配置

在JavaConfig中引用xml配置

使用@ImportResource(“classpath:cdconfig.xml”)

在JavaConfig中導入其他Java配置

@Import(CDConfig.class)

在Jxml中導入JavaCOnfig

<bean class = "***.CDConfig" />

用<import resoune="***.xml"/> 導入其他xml配置