1. 程式人生 > >Spring系列(二) Bean裝配

Spring系列(二) Bean裝配

fig 攔截 首字母 文種 屬性 應用 管理 兩個 兩種

創建應用對象之間協作關系的行為稱為裝配(wiring), 這也是DI的本質.

Spring中裝配Bean的方式

Spring提供了三種裝配Bean的方式.

  1. 隱式的Bean發現機制和自動裝配
  2. Java Config
  3. Xml Config

Spring可以任意選擇三種方式其中的一種或多種組合. 但建議盡量使用自動裝配方式以避免產生繁雜的xml配置文件及java代碼, 其次是使用類型安全的Java Config, 如果都滿足不了需求則最後再考慮xml config.

自動配置

借助於下面兩個方面Spring可以實現自動化Bean配置.

  1. 組件掃描(component scanning): 自動發現上下文種創建的bean
  2. 自動專配(autowiring) 自動創建對象間依賴

一. 組件掃描:

  • @Component 註解標記的java類會作為組件類. 帶參的@Component("beanid"), 參數為bean的名稱, 默認為首字母小寫的類名. @Component 等同 @Named 註解;
    對應xml配置節點
  • @ComponentScan 用來啟動組件掃描, 默認的掃描範圍是該註解標記的類所在的包. 帶參的 @ComponentScan(basePackages={"basePackage1","basePackage2"}) 可以指定掃描的包範圍 ; 帶參的 @ComponentScan(basePackageClasses={ClassNameA.class,InterfaceB.class})
    這些類或接口所在的包將作為掃描的基礎包範圍, 相比指定字符串的基礎包, 這種方式提供了類型安全性(重構友好的);
    對應的xml配置節點是

二. 自動裝配

  • @AutoWired 提供了自動裝配能力. 構造器註入和setter註入均可以使用該註解, 事實上它可以在任何方法上發揮作用.@AutoWired(required=false) 設置為false在沒有匹配到bean時不會拋出異常. @AutoWired等同於@Inject

Java Config

對於無法使用@Conmponent@Autowired註解的, 比如第三方類庫的組件, 可以使用java config的方式裝配. 同時, javaconfig也是java代碼, 他們不應該包含任何業務代碼, 實際上兩者應該完全分開,所以一般會將java config代碼放在單獨的包中.

  • @Configuration 註解標識類是一個配置類.
  • @Bean 註解的方法聲明為返回bean. @Bean(name=‘methodname‘) 參數標識bean的id名稱, 默認為方法名稱.
@Bean
public A getA(){
    return new A();
}

@Bean
public B getB(){
    return new B(getA());
}

@Bean
public C getC(){
    return new C(getA());
}

在上面代碼中構建組件B,C使用的構造器註入了A的beangetA(), 在一般的java程序中B,C的Bean會分別持有A的不同實例, 但Spring中不是這樣, 所有getA()會被攔截, 並返回同一個bean. 默認情況下Spring的bean都是單例的.

可以使用更為簡單的方式創建B,C的bean, 代碼如下:

@Bean
public B getB(){
    return new B(A a); // 也可以使用setter方式, 或者任何其他方式創建bean
}

@Bean
public C getC(){
    return new C(A a);
}
  • @Import({ClassnameA.class,ClassnameB.class}) 對於不同位置的bean, javaconfig可以使用此註解導入其他配置類.

XML Config

XML是Spring最原始的裝配方式, 熟悉Xml config對了解歷史項目, 以及漸進重構到java config或自動配置都是有幫助的.

xml配置構造器(setter)註入的方式有兩種, 兩種方式各有利弊:

  1. c-命名控制 或 p-命名空間 特點是簡潔, 但不能註入集合; 使用時需要引入XSD.
  • 配置文件的頂部需要聲明多個XSD.
  • <bean class="com.xlx.c02.MyClass"> 聲明了一個bean, 默認id為com.xlx.c02.MyClass#0, 可以使用屬性id為bean指定名稱<bean id="myclass" class="com.xlx.c02.MyClass">.
  • <constructor-arg> 用來配置構造器註入的參數, 引用其他bean時使用<constructor-arg ref="otherBeanId">, 等同c-命名空間的屬性c:otherBean-ref=‘otherBeanId‘, 或者參數數字索引c:_0-ref=‘otherBeanId‘(單參數可以省略數字); 也可以註入字面量值<constructor-arg value="this is value"> 等同c-命名空間的屬性c:_name=‘jery‘,或 c:_0=‘jery‘(單參數可省略數字)
  • 裝配集合
<constuctor-arg>
    <list>
        <value>first</value>
        <value>second</value>
    </list>
</constuctor-arg>
  • 設置屬性: <property name="propertyName" ref="beanId">p:propertyName-ref="beanId"
  • util 命名空間的功能可以簡化一些字面量屬性設置, 同樣,需要首先聲明XSD.
<!--定義集合-->
<util:list id="trackList">
    <value>first</value>
    <value>second</value>
</util:list>

<!--p-命名的方式引用集合-->
p:tracks-ref="trackList"

混合配置

一. Java Config引用其他

  • @Import 可以導入java配置類
  • @ImportResource 可以導入xml配置, 如@ImportResource("classpath:my-config.xml")

二. XML Config 引用其他

  • <import resource=‘my-config.xml‘> 引用其他xml配置
  • <bean> 引用java config

不管如何引用, 創建一個根配置會使配置更具層次, 更易於閱讀管理.

Spring系列(二) Bean裝配