啥是Spring Bean
比較官方的解釋是 Spring Bean是事物處理元件類和實體類(POJO)物件的總稱,是能夠被例項化、能夠被spring容器管理的java物件。可以把bean看做是一個元件,這個元件用來具體實現某個業務功能。總結性的講,Bean就是由IOC容器初始化、裝配及管理的物件,除此之外,和程式中的其他物件沒有區別。
怎麼使用Bean呢在spring中bean是由spring容器建立和管理的,各元件之間的依賴關係也是由spring容器管理的,這在很大程度上減少了開發者的工作量。但是你也不是什麼都不需要做的,你要告訴spring要建立哪些bean並且如何將這些bean裝配在一起。看個圖吧:
Spring Bean 的裝配①基於xml配置裝配
宣告一個簡單的bean,在xml中可以按照如下形式宣告一個bean:
<bean id=”foo” class="com.test.Foo" > <property name=”fooPro” value=”proVal”> <property name=”otherObj” ref=”otherObj”></bean>複製程式碼
這裡聲明瞭一個簡單的Bean,建立Bean的類由class屬性指定(需要全限定類名),id是Bean的唯一標識,如果沒有指定id屬性的值則取許可權定類名作為id,com.test.Foo類的定義如下:
Public Class Foo{ private string fooPro; private OtherObj otherObj; public void setFooPro(string fooPro){ this.fooPro = fooPro; } public void setOtherObj (OtherObj otherObj){ this.otherObj = otherObj; } …}複製程式碼
<property>元素實現屬性注入,即將“proVal”賦值給com.test.Foo的“fooPro”屬性,這裡注入的是一個常量值。如果該Bean依賴於另一個Bean,那麼使用ref屬性代替value屬性將所依賴的Bean注入,ref屬性的值指向的是依賴的Bean的id。為了讓配置檔案變得簡潔,Spring提供了p-名稱空間來替代property元素,作用是相同的,簡潔配置如下:
<bean id=”foo” class="com.test.Foo" p:fooPro=”proVal” p:otherObj-ref=“otherObj” ></bean>複製程式碼
常量值屬性的注入為:p:屬性名=”屬性值”,Bean屬性的注入:p:屬性名-ref=”引用的Bean的id”。以上使用的是setter方法注入,Spring還提供了一種構造器注入的方式,簡單介紹一下(使用的較少,一般都是用setter注入的形式):
<bean id=”foo” class="com.test.Foo" > <constructor-arg value=”proVal”> <constructor-arg ref=”otherObj”></bean>複製程式碼
屬性值的注入是按建構函式中的引數順序依次賦值的。
②基於Java程式碼裝配
使用Java程式碼裝配首先需要建立一個配置類(JavaConfig)
@Configurationpublic class FooConf{ @Bean public OtherObj otherObj(){ return new OtherObj(); }}複製程式碼
@Configuration表明該類是一個配置類,@Bean註解用於宣告一個Bean,@Bean註解的方法通知Spring該方法會返回一個Bean並且會註冊為Spring應用上下文的Bean。
Spring從兩個角度實現自動化裝配:
第一步:元件掃描(component scanning),Spring會自動發現應用上下文中所建立的bean。
第二不步:自動裝配( autowiring),Spring自動滿足bean之間的依賴。
建立能被掃描到的Bean:
@Componentpublic class Foo(){}複製程式碼
@Component註解表明該類是一個元件類,它將通知Spring為該類建立一個Bean。那麼該如何讓Spring去掃描@Component註解的類呢?有兩種方式:
使用@ComponentScan註解啟用元件掃描
@Configuration@ComponentScanpublic class FooConf{}複製程式碼
如果沒有其他配置的話,@ComponentScan預設會掃描與配置類相同的包,查詢帶有@Component註解的類,可以使用basePackages屬性設定掃描的基礎包。
使用xml啟用元件掃描
在xml配置檔案中新增<context:component-scan base-package=”要掃描的基礎包” />,作用同@ComponentScan註解。
@Component註解能夠讓Foo類注入到Spring容器中,但是如果Foo類依賴於其他類怎麼辦呢?使用@AutoWried註解。
@Componentpublic class Foo{ //成員變數使用@AutoWired @AutoWried private OtherObj otherObj; ……}@Componentpublic class Foo{ private OtherObj otherObj; //構造方法使用@AutoWired @AutoWried public Foo (OtherObj otherObj){ this.otherObj = otherObj; }}@Componentpublic class Foo{ private OtherObj otherObj; //Setter方法使用@AutoWired @AutoWried Public void setOtherObj (OtherObj otherObj){ this.otherObj = otherObj; }}複製程式碼
如上,@AutoWried註解能夠用在構造器或者setter方法或者成員變數上,作用就是把Foo類依賴的Bean注入進來。
其實在啟動spring IoC時,容器自動裝載了一個AutowiredAnnotationBeanPostProcessor後置處理器,當容器掃描到@Autowied、@Resource或@Inject時,就會在IoC容器自動查詢需要的bean,並裝配給該物件的屬性。
@Resource也可以把Foo類以來的Bean注入進來,但是@AutoWired預設是按型別裝配,@Resource是按名字裝配。當依賴Bean有多個實現類時,就可以使用@Resource註解裝配指定的實現類(@Resource(name="otherObjImpl1")……)。