# 【第六章】 AOP 之 6.2 AOP的HelloWorld ——跟我學spring3
###
### 6.2.1? 準備環境
首先準備開發需要的jar包,請到spring-framework-3.0.5.RELEASE-dependencies.zip和spring-framework-3.0.5.RELEASE-with-docs中查找如下jar包:
```
org.springframework.aop-3.0.5.RELEASE.jar
com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
com.springsource.org.aopalliance-1.0.0.jar
com.springsource.net.sf.cglib-2.2.0.jar
```
將這些jar包添加到“Build Path”下。
### 6.2.2? 定義目標類
1)定義目標接口:
1. package?cn.javass.spring.chapter6.service;??
2. public?interface?IHelloWorldService?{??
3. public?void?sayHello();??
4. }??
2)定義目標接口實現:
1. package?cn.javass.spring.chapter6.service.impl;??
2. import?cn.javass.spring.chapter6.service.IHelloWorldService;??
3. public?class?HelloWorldService?implements?IHelloWorldService?{??
4. @Override??
5. public?void?sayHello()?{??
6. System.out.println("============Hello?World!");??
7. }??
8. }??
注:在日常開發中最后將業務邏輯定義在一個專門的service包下,而實現定義在service包下的impl包中,服務接口以IXXXService形式,而服務實現就是XXXService,這就是規約設計,見名知義。當然可以使用公司內部更好的形式,只要大家都好理解就可以了。
### 6.2.2? 定義切面支持類
有了目標類,該定義切面了,切面就是通知和切入點的組合,而切面是通過配置方式定義的,因此這定義切面前,我們需要定義切面支持類,切面支持類提供了通知實現:
1. package?cn.javass.spring.chapter6.aop;??
2. public?class?HelloWorldAspect?{??
3. //前置通知??
4. public?void?beforeAdvice()?{??
5. System.out.println("===========before?advice");??
6. }??
7. //后置最終通知??
8. public?void?afterFinallyAdvice()?{??
9. System.out.println("===========after?finally?advice");??
10. }??
11. }??
此處HelloWorldAspect類不是真正的切面實現,只是定義了通知實現的類,在此我們可以把它看作就是缺少了切入點的切面。
注:對于AOP相關類最后專門放到一個包下,如“aop”包,因為AOP是動態織入的,所以如果某個目標類被AOP攔截了并應用了通知,可能很難發現這個通知實現在哪個包里,因此推薦使用規約命名,方便以后維護人員查找相應的AOP實現。
### 6.2.3? 在XML中進行配置
有了通知實現,那就讓我們來配置切面吧:
1)首先配置AOP需要aop命名空間,配置頭如下:
1. <?xml?version="1.0"?encoding="UTF-8"?>??
2. <beans??xmlns="http://www.springframework.org/schema/beans"??
3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"??
4. xmlns:aop="http://www.springframework.org/schema/aop"??
5. xsi:schemaLocation="??
6. http://www.springframework.org/schema/beans??
7. http://www.springframework.org/schema/beans/spring-beans-3.0.xsd??
8. http://www.springframework.org/schema/aop??
9. http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">??
10. </beans>??
2)配置目標類:
1. <bean?id="helloWorldService"??
2. class="cn.javass.spring.chapter6.service.impl.HelloWorldService"/>??
3)配置切面:
1. <bean?id="aspect"?class="cn.javass.spring.chapter6.aop.HelloWorldAspect"/>??
2. <aop:config>??
3. <aop:pointcut?id="pointcut"?expression="execution(*?cn.javass..*.*(..))"/>??
4. <aop:aspect?ref="aspect">??
5. <aop:before?pointcut-ref="pointcut"?method="beforeAdvice"/>??
6. <aop:after?pointcut="execution(*?cn.javass..*.*(..))"?method="afterFinallyAdvice"/>??
7. </aop:aspect>??
8. </aop:config>??
切入點使用<aop:config>標簽下的<aop:pointcut>配置,expression屬性用于定義切入點模式,默認是AspectJ語法,“execution(* cn.javass..*.*(..))”表示匹配cn.javass包及子包下的任何方法執行。
切面使用<aop:config>標簽下的<aop:aspect>標簽配置,其中“ref”用來引用切面支持類的方法。
前置通知使用<aop:aspect>標簽下的<aop:before>標簽來定義,pointcut-ref屬性用于引用切入點Bean,而method用來引用切面通知實現類中的方法,該方法就是通知實現,即在目標類方法執行之前調用的方法。
最終通知使用<aop:aspect>標簽下的<aop:after >標簽來定義,切入點除了使用pointcut-ref屬性來引用已經存在的切入點,也可以使用pointcut屬性來定義,如pointcut="execution(* cn.javass..*.*(..))",method屬性同樣是指定通知實現,即在目標類方法執行之后調用的方法。
### 6.2.4 ? ?運行測試
測試類非常簡單,調用被代理Bean跟調用普通Bean完全一樣,Spring AOP將為目標對象創建AOP代理,具體測試代碼如下:
1. package?cn.javass.spring.chapter6;??
2. import?org.junit.Test;??
3. import?org.springframework.context.ApplicationContext;??
4. import?org.springframework.context.support.ClassPathXmlApplicationContext;??
5. import?cn.javass.spring.chapter6.service.IHelloWorldService;??
6. import?cn.javass.spring.chapter6.service.IPayService;??
7. public?class?AopTest?{??
8. @Test??
9. public?void?testHelloworld()?{??
10. ApplicationContext?ctx?=??new?ClassPathXmlApplicationContext("chapter6/helloworld.xml");??
11. IHelloWorldService?helloworldService?=??
12. ctx.getBean("helloWorldService",?IHelloWorldService.class);??
13. helloworldService.sayHello();??
14. }??
15. }??
該測試將輸出如下如下內容:
1. ===========before?advice??
2. ============Hello?World!??
3. ===========after?finally?advice??
從輸出我們可以看出:前置通知在切入點選擇的連接點(方法)之前允許,而后置通知將在連接點(方法)之后執行,具體生成AOP代理及執行過程如圖6-4所示。

圖6-4 Spring AOP框架生成AOP代理過程
原創內容 轉自請注明出處【[http://sishuok.com/forum/blogPost/list/2467.html](http://sishuok.com/forum/blogPost/list/2467.html)】
- 跟我學 Spring3
- 【第二章】 IoC 之 2.1 IoC基礎 ——跟我學Spring3
- 【第二章】 IoC 之 2.2 IoC 容器基本原理 ——跟我學Spring3
- 【第二章】 IoC 之 2.3 IoC的配置使用——跟我學Spring3
- 【第三章】 DI 之 3.1 DI的配置使用 ——跟我學spring3
- 【第三章】 DI 之 3.2 循環依賴 ——跟我學spring3
- 【第三章】 DI 之 3.3 更多DI的知識 ——跟我學spring3
- 【第三章】 DI 之 3.4 Bean的作用域 ——跟我學spring3
- 【第四章】 資源 之 4.1 基礎知識 ——跟我學spring3
- 【第四章】 資源 之 4.2 內置Resource實現 ——跟我學spring3
- 【第四章】 資源 之 4.3 訪問Resource ——跟我學spring3
- 【第四章】 資源 之 4.4 Resource通配符路徑 ——跟我學spring3
- 【第五章】Spring表達式語言 之 5.1 概述 5.2 SpEL基礎 ——跟我學spring3
- 【第五章】Spring表達式語言 之 5.3 SpEL語法 ——跟我學spring3
- 【第五章】Spring表達式語言 之 5.4在Bean定義中使用EL—跟我學spring3
- 【第六章】 AOP 之 6.1 AOP基礎 ——跟我學spring3
- 【第六章】 AOP 之 6.2 AOP的HelloWorld ——跟我學spring3
- 【第六章】 AOP 之 6.3 基于Schema的AOP ——跟我學spring3
- 【第六章】 AOP 之 6.4 基于@AspectJ的AOP ——跟我學spring3
- 【第六章】 AOP 之 6.5 AspectJ切入點語法詳解 ——跟我學spring3
- 【第六章】 AOP 之 6.6 通知參數 ——跟我學spring3
- 【第六章】 AOP 之 6.7 通知順序 ——跟我學spring3
- 【第六章】 AOP 之 6.8 切面實例化模型 ——跟我學spring3
- 【第六章】 AOP 之 6.9 代理機制 ——跟我學spring3
- 【第七章】 對JDBC的支持 之 7.1 概述 ——跟我學spring3
- 【第七章】 對JDBC的支持 之 7.2 JDBC模板類 ——跟我學spring3
- 【第七章】 對JDBC的支持 之 7.3 關系數據庫操作對象化 ——跟我學spring3
- 【第七章】 對JDBC的支持 之 7.4 Spring提供的其它幫助 ——跟我學spring3【私塾在線原創】
- 【第七章】 對JDBC的支持 之 7.5 集成Spring JDBC及最佳實踐 ——跟我學spring3
- 【第八章】 對ORM的支持 之 8.1 概述 ——跟我學spring3
- 【第八章】 對ORM的支持 之 8.2 集成Hibernate3 ——跟我學spring3
- 【第八章】 對ORM的支持 之 8.3 集成iBATIS ——跟我學spring3
- 【第八章】 對ORM的支持 之 8.4 集成JPA ——跟我學spring3
- 【第九章】 Spring的事務 之 9.1 數據庫事務概述 ——跟我學spring3
- 【第九章】 Spring的事務 之 9.2 事務管理器 ——跟我學spring3
- 【第九章】 Spring的事務 之 9.3 編程式事務 ——跟我學spring3
- 【第九章】 Spring的事務 之 9.4 聲明式事務 ——跟我學spring3
- 【第十章】集成其它Web框架 之 10.1 概述 ——跟我學spring3
- 【第十章】集成其它Web框架 之 10.2 集成Struts1.x ——跟我學spring3
- 【第十章】集成其它Web框架 之 10.3 集成Struts2.x ——跟我學spring3
- 【第十章】集成其它Web框架 之 10.4 集成JSF ——跟我學spring3
- 【第十一章】 SSH集成開發積分商城 之 11.1 概述 ——跟我學spring3
- 【第十一章】 SSH集成開發積分商城 之 11.2 實現通用層 ——跟我學spring3
- 【第十一章】 SSH集成開發積分商城 之 11.3 實現積分商城層 ——跟我學spring3
- 【第十二章】零配置 之 12.1 概述 ——跟我學spring3
- 【第十二章】零配置 之 12.2 注解實現Bean依賴注入 ——跟我學spring3
- 【第十二章】零配置 之 12.3 注解實現Bean定義 ——跟我學spring3
- 【第十二章】零配置 之 12.4 基于Java類定義Bean配置元數據 ——跟我學spring3
- 【第十二章】零配置 之 12.5 綜合示例-積分商城 ——跟我學spring3
- 【第十三章】 測試 之 13.1 概述 13.2 單元測試 ——跟我學spring3
- 【第十三章】 測試 之 13.3 集成測試 ——跟我學spring3
- 跟我學 Spring MVC
- SpringMVC + spring3.1.1 + hibernate4.1.0 集成及常見問題總結
- Spring Web MVC中的頁面緩存支持 ——跟我學SpringMVC系列
- Spring3 Web MVC下的數據類型轉換(第一篇)——《跟我學Spring3 Web MVC》搶先看
- Spring3 Web MVC下的數據格式化(第二篇)——《跟我學Spring3 Web MVC》搶先看
- 第一章 Web MVC簡介 —— 跟開濤學SpringMVC
- 第二章 Spring MVC入門 —— 跟開濤學SpringMVC
- 第三章 DispatcherServlet詳解 ——跟開濤學SpringMVC
- 第四章 Controller接口控制器詳解(1)——跟著開濤學SpringMVC
- 第四章 Controller接口控制器詳解(2)——跟著開濤學SpringMVC
- 第四章 Controller接口控制器詳解(3)——跟著開濤學SpringMVC
- 第四章 Controller接口控制器詳解 (4)——跟著開濤學SpringMVC
- 第四章 Controller接口控制器詳解(5)——跟著開濤學SpringMVC
- 跟著開濤學SpringMVC 第一章源代碼下載
- 第二章 Spring MVC入門 源代碼下載
- 第四章 Controller接口控制器詳解 源代碼下載
- 第四章 Controller接口控制器詳解(6)——跟著開濤學SpringMVC
- 第四章 Controller接口控制器詳解(7 完)——跟著開濤學SpringMVC
- 第五章 處理器攔截器詳解——跟著開濤學SpringMVC
- 源代碼下載 第五章 處理器攔截器詳解——跟著開濤學SpringMVC
- 注解式控制器運行流程及處理器定義 第六章 注解式控制器詳解——跟著開濤學SpringMVC
- 源代碼下載 第六章 注解式控制器詳解
- SpringMVC3強大的請求映射規則詳解 第六章 注解式控制器詳解——跟著開濤學SpringMVC
- Spring MVC 3.1新特性 生產者、消費者請求限定 —— 第六章 注解式控制器詳解——跟著開濤學SpringMVC
- SpringMVC強大的數據綁定(1)——第六章 注解式控制器詳解——跟著開濤學SpringMVC
- SpringMVC強大的數據綁定(2)——第六章 注解式控制器詳解——跟著開濤學SpringMVC
- SpringMVC數據類型轉換——第七章 注解式控制器的數據驗證、類型轉換及格式化——跟著開濤學SpringMVC
- SpringMVC數據格式化——第七章 注解式控制器的數據驗證、類型轉換及格式化——跟著開濤學SpringMVC
- SpringMVC數據驗證——第七章 注解式控制器的數據驗證、類型轉換及格式化——跟著開濤學SpringMVC