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要進行裝備的是引用而不是字面量。
將字面量注入到屬性中