Spring 基於 Annotation 裝配 Bean 演練
在 Spring 中,儘管使用 XML 配置文件可以實現 Bean 的裝配工作,但如果應用中 Bean 的數量較多,會導致 XML 配置文件過於臃腫,從而給維護和升級帶來一定的困難。
Java 從 JDK 5.0 以後,提供了 Annotation(註解)功能,Spring 也提供了對 Annotation 技術的全面支持。Spring3 中定義了一系列的 Annotation(註解),常用的註解如下。
1)@Component
可以使用此註解描述 Spring 中的 Bean,但它是一個泛化的概念,僅僅表示一個組件(Bean),並且可以作用在任何層次。使用時只需將該註解標註在相應類上即可
2)@Repository
用於將數據訪問層(DAO層)的類標識爲 Spring 中的 Bean,其功能與 @Component 相同
3)@Service
通常作用在業務層(Service 層),用於將業務層的類標識爲 Spring 中的 Bean,其功能與 @Component 相同
4)@Controller
通常作用在控制層(如 Struts2 的 Action),用於將控制層的類標識爲 Spring 中的 Bean,其功能與 @Component 相同
5)@Autowired
用於對 Bean 的屬性變量、屬性的 Set 方法及構造函數進行標註,配合對應的註解處理器完成 Bean 的自動配置工作。默認按照 Bean 的類型進行裝配
6)@Resource
其作用與 Autowired 一樣。其區別在於 @Autowired 默認按照 Bean 類型裝配,而 @Resource 默認按照 Bean 實例名稱進行裝配
@Resource 中有兩個重要屬性:name 和 type。Spring 將 name 屬性解析爲 Bean 實例名稱,type 屬性解析爲 Bean 實例類型。如果指定 name 屬性,則按實例名稱進行裝配;如果指定 type 屬性,則按 Bean 類型進行裝配。如果都不指定,則先按 Bean 實例名稱裝配,如果不能匹配,則再按照 Bean 類型進行裝配;如果都無法匹配,則拋出 NoSuchBeanDefinitionException 異常。
7)@Qualifier
與 @Autowired 註解配合使用,會將默認的按 Bean 類型裝配修改爲按 Bean 的實例名稱裝配,Bean 的實例名稱由 @Qualifier 註解的參數指定
接下來,對 Spring 基於 Annotation 裝配 Bean 進行演練。
1. 創建 DAO 層接口
在 src 目錄下創建一個名爲 com.mengma.annotation 的包,在該包下創建一個名爲 PersonDao 的接口,並添加一個 add() 方法,如下所示:
package com.mengma.annotation;
public interface PersonDao {
public void add();
}
2. 創建 DAO 層接口的實現類
在 com.mengma.annotation 包下創建 PersonDao 接口的實現類 PersonDaoImpl,編輯後如下所示:
package com.mengma.annotation;
import org.springframework.stereotype.Repository;
@Repository("personDao")
public class PersonDaoImpl implements PersonDao {
@Override
public void add() {
// TODO Auto-generated method stub
System.out.println("Dao層的add()方法執行了...");
}
}
上述代碼中,首先使用 @Repository 註解將 PersonDaoImpl 類標識爲 Spring 中的 Bean,其寫法相當於配置文件中 <bean id="personDao"class="com.mengma.annotation.PersonDaoImpl"/> 的書寫。然後在 add() 方法中輸出一句話,用於驗證是否成功調用了該方法。
3. 創建 Service 層接口
在 com.mengma.annotation 包下創建一個名爲 PersonService 的接口,並添加一個 add() 方法,如下所示:
package com.mengma.annotation;
public interface PersonService {
public void add();
}
4. 創建 Service 層接口的實現類
在 com.mengma.annotation 包下創建 PersonService 接口的實現類 PersonServiceImpl,編輯後如下所示:
package com.mengma.annotation;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
@Service("personService")
public class PersonServiceImpl implements PersonService {
@Resource(name = "personDao")
private PersonDao personDao;
public PersonDao getPersonDao() {
return personDao;
}
@Override
public void add() {
// TODO Auto-generated method stub
personDao.add();// 調用personDao中的add()方法
System.out.println("Service層的add()方法執行了...");
}
}
上述代碼中,首先使用 @Service 註解將 PersonServiceImpl 類標識爲 Spring 中的 Bean,其寫法相當於配置文件中 <bean id="personService"class="com.mengma.annotation.PersonServiceImpl"/> 的書寫。
然後使用 @Resource 註解標註在屬性 personDao 上(也可標註在 personDao 的 setPersonDao() 方法上),這相當於配置文件中 <property name="personDao"ref="personDao"/> 的寫法。最後在該類的 add() 方法中調用 personDao 中的 add() 方法,並輸出一句話。
5. 創建 Action
在 com.mengma.annotation 包下創建一個名爲 PersonAction 的類,編輯後如下所示:
package com.mengma.annotation;
import javax.annotation.Resource;
import org.springframework.stereotype.Controller;
@Controller("personAction")
public class PersonAction {
@Resource(name = "personService")
private PersonService personService;
public PersonService getPersonService() {
return personService;
}
public void add() {
personService.add();// 調用personService中的add()方法
System.out.println("Action層的add()方法執行了...");
}
}
上述代碼中,首先使用 @Controller 註解標註 PersonAction 類,其寫法相當於在配置文件中編寫 <bean id="personAction"class="com.mengma.annotation.PersonAction"/>。
然後使用了 @Resource 註解標註在 personService 上,這相當於在配置文件內編寫 <property name="personService"ref="personService"/>。
最後在其 add() 方法中調用了 personService 中的 add() 方法,並輸出一句話。
6. 創建 Spring 配置文件
在 com.mengma.annotation 包下創建一個名爲 applicationContext.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"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!--使用context命名空間,通知spring掃描指定目錄,進行註解的解析-->
<context:component-scan base-package="com.mengma.annotation"/>
</beans>
第 18 行代碼中,使用 context 命名空間的 component-scan 元素進行註解的掃描,其 base-package 屬性用於通知 spring 所需要掃描的目錄。
7. 創建測試類
在 com.mengma.annotation 包下創建一個名爲 AnnotationTest 的測試類,編輯後如下所示:
package com.mengma.annotation;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class AnnotationTest {
@Test
public void test() {
// 定義Spring配置文件路徑
String xmlPath = "com/mengma/annotation/applicationContext.xml";
// 初始化Spring容器,加載配置文件,並對bean進行實例化
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
// 獲得personAction實例
PersonAction personAction = (PersonAction) applicationContext.getBean("personAction");
// 調用personAction中的add()方法
personAction.add();
}
}
上述代碼中,首先通過加載配置文件並獲取 personAction 的實例,然後調用該實例的 add() 方法。
8. 運行程序並查看結果
使用 JUnit 測試運行 AnnotationTest,運行成功後,輸出結果如圖:
從輸出結果中可以看出,DAO 層、Service 層和 Action 層的 add() 方法都成功輸出了結果。由此可知,使用 Annotation 裝配 Bean 的方式已經成功實現了。