- Spring+Spring MVC+MyBatis從零開始學
- 吳為勝 楊章偉
- 2496字
- 2019-11-22 18:31:39
2.3 Bean的裝配方式
Bean的裝配可以理解為依賴關系注入,Bean的裝配方式即Bean依賴注入的方式。Spring容器支持多種形式的Bean裝配方式,如基于XML的裝配、基于Annotation(注解)的裝配和自動裝配等。本節主要講解這3種裝配方式的使用。
2.3.1 基于XML的裝配
Spring提供了兩種基于XML的裝配方式:設值注入(Setter Injection)和構造注入(Constructor Injection)。下面講解如何在XML配置文件中使用這兩種注入方式來實現基于XML的裝配。
在Spring實例化Bean的過程中,Spring首先會調用Bean的默認構造方法來實例化Bean對象,然后通過反射的方式調用setter()方法來注入屬性值。因此,設值注入要求一個Bean必須滿足以下兩點要求:
- Bean類必須提供一個默認的無參構造方法。
- Bean類必須為需要注入的屬性提供對應的setter()方法。
使用設值注入時,在Spring配置文件中需要使用<bean>元素的子元素<property>來為每個屬性注入值;而使用構造注入時,在配置文件中需要使用<bean>元素的子元素<constructor-arg>來定義構造方法的參數,可以使用其value屬性(或子元素)來設置該參數的值。
【示例2-2】下面通過一個案例來演示基于XML方式的Bean的裝配。
(1)在項目chapter02的src目錄下創建一個com.ssm.assemble包,在該包中創建User類,并在類中定義userName、password和list集合3個屬性及對應的setter()方法,如文件2.4所示。
文件2.4 User.java

在文件2.4的第11~16行、第26~28行,由于要使用構造注入,因此需要編寫有參和無參的構造方法。
(2)在Spring的配置文件application.xml(文件2.2)中,增加通過構造注入和設值注入的方法裝配User實例的兩個Bean,代碼如下所示。

在上述代碼中,<constructor-arg>元素用于定義構造方法的參數,其屬性index表示其索引(從0開始),value屬性用于設置注入的值,其子元素<list>為User類中對應的list集合屬性注入值。然后又使用設值注入方法裝配User類的實例,其中<property>元素用于調用Bean實例中的setter()方法完成屬性賦值,從而完成依賴注入,而其子元素<list>同樣為User類中對應的list集合屬性注入值。
(3)在com.ssm.assemble包中創建測試類XmlAssembleTest,在類中分別獲取并輸出配置文件中的user1和user2實例,如文件2.5所示。
文件2.5 XmlAssembleTest.java

執行程序后,控制臺輸出結果如圖2.3所示。可以看出,已經成功地使用基于XML裝配的構造注入和設值注入兩種方式裝配了User實例。

圖2.3 運行結果
2.3.2 基于Annotation的裝配
在Spring中,盡管使用XML配置文件可以實現Bean的裝配工作,但如果應用中有很多Bean,就會導致XML配置文件過于臃腫,給以后的維護和升級工作帶來一定的困難。為此,Spring提供了對Annotation(注解)技術的全面支持。
Spring中定義了一系列的注解,常用的注解如表2.3所示。
表2.3 Spring的常用注解

注意
在表2.3的幾個注解中,雖然@Repository、@Service和@Controller的功能與@Component注解的功能相同,但為了使標注類本身用途更加清晰,建議在實際開發中使用@Repository、@Service和@Controller分別對實現類進行標注。
【示例2-3】接下來,通過一個案例來演示如何通過這些注解來裝配Bean。
(1)在chapter02項目的src目錄下創建一個com.ssm.annotation包,在該包中創建接口UserDao,并在接口中定義一個save()方法,如文件2.6所示。
文件2.6 UserDao.java

(2)在com.ssm.annotation包中創建UserDao接口的實現類UserDaoImpl,該類需要實現接口中的save()方法,如文件2.7所示。
文件2.7 UserDaoImpl.java

在文件2.7中,首先使用@Repository注解將UserDaoImpl類標識為Spring中的Bean,其寫法相當于配置文件中<bean id="user Dao" class=" com.ssm.annotation.UserDaoImpl />的編寫。然后在save()方法中打印一句話,用于驗證是否成功調用了該方法。
(3)在com.ssm.annotation包中創建接口UserService,在接口中同樣定義一個save()方法,如文件2.8所示。
文件2.8 UserService.java

(4)在com.ssm.annotation包中創建UserService接口的實現類UserServiceImpl,該類需要實現接口中的save()方法,如文件2.9所示。
文件2.9 UserServiceImpl.java

在文件2.9中,首先使用@Service注解將UserServiceImpl類標識為Spring中的Bean,這相當于配置文件中<bean id= "userService" class="com.ssm.annotation.UserServiceImpl"/>的編寫;然后使用@Resource注解標注在屬性userDao上,這相當于配置文件中<property name="userDao" ref="userDao”/>的寫法;最后在該類的save()方法中調用userData中的save()方法,并輸出一句話。
(5)在com.ssm.annotation包中創建控制器類UserController,如文件2.10所示。
文件2.10 UserController.java

首先使用@Controller注解標注了UserController類,這相當于在配置文件中編寫<bean id="userController" class=" com.ssm.annotation.UserController"/>;然后使用@Resource注解標注在userService屬性上,這相當于在配置文件中編寫<property name="userService" ref=" userService"/>;最后在其save()方法中調用了userService中的save()方法,并輸出一句話。
(6)在com.ssm.annotation包中創建配置文件beans1.xml,在配置文件中編寫基于Annotation裝配的代碼,如文件2.11所示。
文件2.11 beans1.xml

從上述代碼可以看出,文件2.11與之前的配置文件有很大不同。首先,在<beans>元素中增加了04、07和08行中包含context的約束信息;然后通過配置<context: annotation-config/>來開啟注解處理器;最后分別定義了3個Bean對應的3個實例。與XML配置方式有所不同的是,這里不再需要配置子元素<property>。
上述Spring配置文件中的注解方式雖然較大程度地簡化了XML文件中Bean的配置,但仍需在Spring配置文件中一一配置相應的Bean,為此Spring注解提供了另一種高效的注解配置方式(對包路徑下的所有Bean文件進行掃描),其配置方式如下:

所以可以將上述文件2.11中的09~14行代碼進行如下替換:

注意
Spring 4.0以上版本使用上面的代碼對指定包中的注解進行掃描前,需要先向項目中導入SpringAOP的JAR包spring-aop-4.3.6.RELEASE.jar,否則程序在運行時會報出“java.lang.NoClassDefFoundError:org/springframework/aop/TargetSource”錯誤。
(7)在com.ssm.annotation包中創建測試類AnnotationAssembleTest,在類中編寫測試方法并定義配置文件的路徑,然后通過Spring容器加載配置文件并獲取UserController實例,最后調用實例中的save()方法,如文件2.12所示。
文件2.12 AnnotationAssembleTest.java

執行程序后,控制臺的輸出結果如圖2.4所示。從中可以看到,Spring容器已成功獲取了UserController的實例,并通過調用實例中的方法執行了各層中的輸出語句,這說明已成功實現了基于Annotation來裝配Bean實例。

圖2.4 運行結果
注意
上述案例中使用@Autowired注解替換@Resource注解也可以達到同樣的效果。
2.3.3 自動裝配
雖然使用注解的方式裝配Bean在一定程度上減少了配置文件中的代碼量,但是也有企業項目中是沒有使用注解方式開發的,那么有沒有什么辦法既可以減少代碼量,又能夠實現Bean的裝配呢?答案是肯定的。Spring的<bean>元素中包含一個autowire屬性,我們可以通過設置autowire的屬性值來自動裝配Bean。所謂自動裝配,就是將一個Bean自動注入其他Bean的Property中。
autowire屬性有5個值,其值及說明如表2.4所示。
表2.4 <bean>元素的autowire屬性值及說明

【示例2-4】下面通過修改2.3.2節中的案例來演示如何使用自動裝配。
(1)修改2.3.2小節中的文件2.9(UserServiceImpl.java)和文件2.10(UserController.java),分別在這兩個文件中增加類屬性的setter()方法。
(2)修改2.3.2小節中的配置文件2.11(beans1.xml),將其修改成自動裝配形式,如文件2.13所示。
文件2.13 beans2.xml

在上述配置文件中,用于配置userService和userController的<bean>元素中除了id和class屬性外,還增加了autowire屬性,并將其屬性值設置為byName。在默認情況下,配置文件中需要通過ref來裝配Bean,但設置了autowire="byName"后,Spring會自動尋找userServiceBean中的屬性,并將其屬性名稱與配置文件中定義的Bean做匹配。由于UserServiceImpl中定義了userDao屬性及其setter()方法,這與配置文件中id為userDao的Bean相匹配,因此Spring會自動地將id為userDao的Bean裝配到id為userService的Bean中。
執行程序后,控制臺的輸出結果與圖2.4相同。
- 數據庫系統教程(第2版)
- PostgreSQL for Data Architects
- x86匯編語言:從實模式到保護模式(第2版)
- QGIS:Becoming a GIS Power User
- Building Serverless Applications with Python
- 零基礎學單片機C語言程序設計
- Python時間序列預測
- Integrating Facebook iOS SDK with Your Application
- Troubleshooting Citrix XenApp?
- Java Web從入門到精通(第2版)
- Mastering jQuery Mobile
- Go Systems Programming
- SOA Patterns with BizTalk Server 2013 and Microsoft Azure(Second Edition)
- 利用Python駕馭Stable Diffusion:原理解析、擴展開發與高級應用(智能系統與技術叢書)
- Alfresco for Administrators