裝配Bean

spring提供了三種bean的裝配機制java

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

 

1、自動化裝配beanspring

CD播放器依賴於CD,只有將CD插入(注入)到CD播放器,CD播放器才能放出音樂。安全

一、spring從兩個角度來實現自動化裝配ide

  • 組件掃描(component scanning):spring會自動發現應用上下文中所建立的bean
  • 自動裝配(autowiring):spring自動知足bean之間的依賴

二、@Component 註解代表該類會做爲組件類,並告知spring要爲這個類建立bean;組件掃描默認不啓用,需組合@ComponentScan 註解使用。ui

三、@ComponentScan 啓用組件掃描,若是沒有其餘配置,@ComponentScan默認會掃描與配置類相同的包。例,CDPlayerConfig類位於soundsystem包中,所以spring將會掃描這個包及這個包下的全部子包,查找帶有@Compnent註解的類,這樣就能發現CompactDisc,而且會在spring中自動爲其建立一個bean;在xml中的使用:<context:componet-scan base-package="com.spring.soundsystem">。component

四、爲組件掃描的bean命名:spring應用上下文中全部的bean都會給定一個ID,@Component註解默認爲ID爲類名首字母小寫,可自定義命名@Component("newName");也可使用Java依賴注入規範中提供的@Named註解爲bean設置ID,如:@Named("newName")。大多數場景中二者可相互替換,但推薦使用@Component,由於@Named註解語意不明。xml

五、設置組件掃描的基礎包對象

@componetScan會以配置類所在的包做爲基礎包(base package)來掃描組件,若是咱們將配置類放在單獨的包中,使其與其餘的代碼區分開來,就須要在@Component的value屬性中指明包的名稱:blog

@Configuration
@ComponentScan("com.spring.soundsystem")
public class CDPlayConfig{
}

  若是想更加清晰的代表設置的基礎包,能夠經過basePackage屬性進行配置:接口

@Configuration
@ComponentScan(basePackages="com.spring.soundsystem")
//@ComponentScan(basePackages{"com.spring.soundsystem","com.spring.video"})
public class CDPlayConfig{
}

  以上方法基礎包爲String類型,這種方法是類型不安全的(not type-safe),@Componet還提供另一種方法,那就是將其指定爲包中所包含的類或者接口

@Configuration
@compnentScan(basePackageClasses={CDPlayer,class,Video.claass})
public class CDPlayerConfig{
}

  六、經過爲bean添加註解實現自動裝配

  @autowired註解可用在類的任何方法上,不只可以用在構造器上,還能用在屬性的Setter方法上;若是沒有匹配的bean,那麼在應用上下文建立的時候,spring會拋出一個異常,爲避免異常,可將@autowired的required屬性設置爲false,即:@autowired(required=false);將required屬性設置爲false時,spring會嘗試執行自動裝配,若是沒有匹配的bean,sping將會讓這個bean處於爲裝配的狀態。同時,須要先在代碼中進行null檢查,不然會出現NullPointerException。若是有多個bean都能知足依賴關係,spring會拋出一個異常,代表沒有明確指定選擇哪一個bean進行自動裝配。可以使用Java依賴注入規範的@Inject註解替換@Autowired。

 

2、經過Java代碼裝配bean(JavaConfig)

一、建立JavaConfig類的關鍵在於爲其添加@Configruration註解,@Configuration註解代表這個類是一個配置類,該類應包含在spring應用上下文中如何建立bean的細節。

二、聲明簡單的bean

// @Bean註解會告訴spring這個方法返回一個對象,該對象要註冊爲spring應用上下文的bean
// 默認狀況下,bean的id與帶有@Bean註解的方法名是同樣的
// 若是想設置一個不一樣的名字,能夠重命名該方法,也能夠經過name屬性指定一個不一樣的名字,@Bean(name = "lonelyHeartsClubBand")
@Bean
public CompactDisc sgtPeppers(){
  return new SgtPeppers();    
}

三、藉助JavaConfig實現注入

在JavaConfig中裝配bean的最簡單方式就是引用建立的bean的方法。

// 看起來CompactDisc是經過調用sgtPeppers()獲得的,但狀況並不是徹底如此。由於sgtPeppers()方法上添加了@Bean註解,spring將會攔截全部對它的調用,並確保直接返回該方法所建立的bean,而不是每次都對其進行實際的調用
@Bean
public CDPlayer cdPlayer(){
  return new CDPlayer(sgtPeppers()) ;
}
// 另外一種理解起來更爲簡單的方式,CDPlayer的構造器實現DI
@Bean
pubic CDPlayer cdPlayer(CompactDisc compactDisc){
    return new CDPlayer(compactDisc);
}
// Setter方法注入
public CDPlayer cdPlayer(CompactDisc compactDisc){
    CDPlayer cdPlayer = new CDPlayer(compactDisc);
    cdPlayer.setCompactDisc(compactDisc);
    return cdPlayer;
}

 

3、經過XML裝配Bean

一、建立一個XML文件,必須以<beans>元素爲根,最爲簡單的Spring xml配置以下

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

</beans>

二、聲明一個簡單的<bean>

// 默認的ID"soundsystem.SgtPeppers#0","#0"是一個計數形式
<bean class="soundsystem.SgePeppers" />
// 爲bena設置一個id
<bean id="compactDisc" class="soundsystem.SgePeppers" />

  當spring發現這個<bean>元素時,它將會調用SgtPeppers的默認構造器來建立bean。須要注意的是,在這個簡單的<bean>聲明中,咱們將bean的類型以字符串的形式設置在了class屬性中。誰能保證設置給class屬性的值是真正的類呢?Spring的XML配置並不能從編譯器的類型檢查中受益。即使它所引用的是實際的類型,若是你重命名了類,會發生什麼呢?

三、藉助構造器注入初始化bean

具體到構造器注入,有兩種基本的配置方案可供選擇:

· <constructor-arg>元素

· 使用spring 3.0所引用的c-命名空間

3.一、構造器注入bean引用

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

  當spring遇到<bean>元素時,他會建立一個CDPlayer實例。<constructor-arg>元素會告知spring要將一個ID爲compactDisc的bean引用傳遞到CDPlayer的構造器中。

c-命名空間是在spring3.0中引入的,他是在XML中更爲簡潔第描述構造器參數的方式,要使用它必需要在XML的頂部聲明其模式。

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

四、將字面變量注入到構造器中

假設要建立CompactDisc的一個新實現

  

<bean id="compactDIs" class="soundsystem.BlankDisc">
    <constructor-arg value="Sgt. Pepper's Loney Hearts Club Band" />
    <constructor-arg value="The Beatles" />
</bean>

  這裏沒有使用「ref」屬性來引用其餘的bean,而是使用了value屬性,經過該屬性代表給定的值要以字面量的形式注入待構造器中(「ref」,引用傳遞,「value」,值傳遞)。

五、設置屬性

如何選擇構造器注入仍是屬性注入?對於強依賴使用構造器注入,二隊可選性的依賴使用屬性注入。

  

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

  <property>元素爲屬性的Setter方法所提供的功能與<constructor-arg>元素爲構造器所提供的功能是同樣的。在本例中,它引用了ID爲compactDisc的bean(經過ref屬性),並將其注入到compactDisc屬性中(經過setCompactDisc()方法)。

spring爲<constructoer-arg>元素提供了c-命名空間做爲替代方案,與之相似,sping提供了更加簡潔的p-命名空間,做爲<property>元素的替代方案。

使用p-命名空間須要進行聲明:

  

咱們可使用p-命名空間,按照如下的方式裝配compactDisc屬性

<bean id="cdPlayer" class="soundsystem.CDPlayer" p:compactDisc-ref="compactDisc">

  "p:"前綴代表咱們設置的是一個屬性,屬性名稱以「-ref」提示spring要進行裝備的是引用而不是字面量。

將字面量注入到屬性中

  

  

相關文章
相關標籤/搜索