在閱讀本文之前,大家可先參閱《簡單理解Spring之IOC和AOP及代碼示例》一文,了解下Spring中IOC和AOP的相關內容。下面進入正題。本篇文章介紹在Spring中如何定義和裝載Java Bean。
業務場景
還是人開車的例子。首先,定義一個Car接口和兩個實現了Benz和BMW,然後定義一個Person類,Person類依賴Car接口。
public interface Car { void go();} public class Benz implements Car { public void go() { System.out.println("benz go......"); }} public class BMW implements Car { public void go() { System.out.println("bmw go......"); }} public class Person { String name = ""; Car car = null; public Car getCar() { return car; } public void setCar(Car car) { this.car = car; } public Person(String name) { this.name=name; } public void Drive(){ System.out.println(name+" is driving ..."); car.go(); }}在Person類中我們可以看到,car對像是該類的依賴對象,需要通過構造方法注入到Person類中。以上的代碼還完全沒有Spring的影子,下面看看Spring是如何來注入
添加Spring依賴
現在很多項目都適用maven來管理依賴,本項目也是如此。我在pom.xml中加入一下依賴節點
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>3.2.6.RELEASE</version></dependency><dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>3.2.6.RELEASE</version></dependency><dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>3.2.6.RELEASE</version></dependency><dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>3.2.6.RELEASE</version></dependency>
將這些dependency節點放入pom.xml文件的dependencies節點下,eclipse會自動下載相關的包到默認位置。
手動定義和裝配Bean
在項目的根目錄中新建一個名叫bean.xml的xml文件,內容如下:
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"><beans> <bean id="car" /> <bean id="tom"> <constructor-arg value="Tom" /> <property name="car" ref="car" /> </bean></beans>
上面的XML文件首先定義了一個id為car的bean,又定義了一個id為tom的bean,car作為tom的依賴,通過<property name="car" ref="car" />的方式被手動地裝配到了tom的car屬性中。
創建應用對象之間協作關係的行為被稱為裝配(wiring),這也是依賴對象注入的本質。
接下來我們在main方法中實例化一個應用上下文對象,並獲取bean中的tom節點
public class App { public static void main( String[] args ) { ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml"); Person tom=(Person) context.getBean("tom"); tom.Drive(); }}運行程序,輸出結果為:
Tom is driving ...bmw go......
自動裝配
再重複一遍,創建應用對象之間協作關係的行為被稱為裝配(wiring),而不是實例化對象的過程。在上面的xml文件中,我通過<property name="car" ref="car" />的方式來裝配了依賴對象,但是隨著應用的不斷發展,xml配置文件肯定會越來越複雜,我們通過ref="car"來關聯id為car的bean的這種方式已經開始落後了。下面我來介紹一下Spring如何實現自動裝配bean。
自動裝配的類型
Spring共四種裝配策略,為了降低本文的複雜性,我介紹兩種常用的策略,byName方式和byType方式。顧名思義,byName方式就是看屬性的名字和bean的id是否相同,在本例中,Person類有一個名叫car的屬性,如果將該類或改屬性設置為自動裝配且裝配策略為byName的話,Spring會去找id為car(必須是同名)的bean。 byType方式是比較類型是否相同。就本例而言,如果將Person類或Person類的car屬性設置為自動裝配且裝配策略為byType的話,由於car屬性是Car類型,所以,Spring在進行自動裝配時,會去找類型為Car或其子類的bean。
使用XML實現自動裝配
下面我來修改代碼,使用xml配置的方式來實現自動裝配。
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"><beans> <bean id="car" /> <bean id="tom" autowire="byName"> <constructor-arg value="Tom" /> </bean></beans>
Person類無需做任何修改。
首先,我去掉了<propertyname="car"ref="car"/>這行代碼,因為它是手工的方式。然後,我將id為tom的bean增加一個屬性autowire="byName",將其設置為通過名字自動裝配依賴,在獲取Person對象時,Person的所有屬性名稱就都有了特殊的含義。 Spring監測到了Person類又一個名叫car的屬性,並且在配置文件中發現了一個id為car的bean,於是乎,就將其自動裝配給了Person的car屬性。
通過註解實現自動裝配
我們將bean.xml做如下修改
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"><beans default-autowire="byName"> <bean id="car" /> <bean id="tom"> <constructor-arg value="Tom" /> </bean></beans>
將id為tom的bean的一個屬性autowire="byName"刪除,然後在跟節點beans中添加一個屬性default-autowire="byName"來設置該文件內定義的所有bean的自動裝配方式的默認值為byName。然後對Person 類做一點修改,在car的setter方法上加上@Autowired註解,來通知Spring對該屬性進行自動裝配。重新運行代碼,輸出結果不變。
@Autowiredpublic void setCar(Car car) { this.car = car;}通過註解來實現自動裝配的話,需要首先在beans根目錄上製定默認的自動裝配方式,然後就不需要在配置文件中為每一個需要自動裝配的bean來配置autowire屬性了(如果方式與默認的不一致,仍然可以單獨配置,來覆蓋默認的自動裝配方式)。註解的方式更加細膩,它可以對需要自動裝配的bean達到屬性級的控制。
在上面的所有代碼中,我們在配置文件中都是使用的org.zdk.springProj1.BMW類作為Person類的依賴,如果由於業務需要,Person類不需要開寶馬車而改開奔馳車了,只需要將該配置修改為org.zdk.springProj1.Benz即可,無需修改任何Java代碼,這就是Spring作為IOC容器的強大之處。
總結
以上就是本文關於spring定義和裝配bean詳解的全部內容,希望對大家有所幫助。感興趣的朋友可以繼續參閱本站:
Java之Spring註解配置bean實例代碼解析
Spring配置使用之Bean生命週期詳解
如有不足之處,歡迎留言指出。感謝朋友們對本站的支持!