前言:
在上一篇中: [Spring框架]Spring AOP基礎入門總結一. 中 咱們已經知道了一個Spring AOP程序是如何開發的, 在這裏呢咱們將基於AspectJ來進行AOP 的總結和學習.
一, AspectJ的概述:
html
AspectJ是一個面向切面的框架,它擴展了Java語言。AspectJ定義了AOP語法因此它有一個專門的編譯器用來生成遵照Java字節編碼規範的Class文件。java
Spring爲了簡化自身的AOP的開發,將AspectJ拿過來做爲Spring自身一個AOP的開發.
二, Spring AspectJ開發實例
2.1 開發所需jar包
2.2 AspectJ 註解開發規範spring
2.2.1 @AspectJ提供不一樣的通知類型express
@Before 前置通知,至關於BeforeAdvice
在執行目標方法以前完成一個操做,得到到切入點信息.
@AfterReturning 後置通知,至關於AfterReturningAdvice
app
1 在目標方法執行以後完成一個操做,得到方法的返回值. 2 3 @AfterReturning(value="execution(* cn.augmentum.aspectj.demo1.CustomerService+.update(..))",returning="result") 4 public void afterReturing(Object result){ 5 System.out.println("後置通知============"+result); 6 }
@Around 環繞通知,至關於MethodInterceptor
框架
1 在目標方法執行的前和執行後完成一個操做,阻止目標方法執行. 2 3 @Around(value="execution(* cn.augmentum.aspectj.demo1.CustomerService+.delete(..))") 4 public Object around(ProceedingJoinPoint joinPoint) throws Throwable{ 5 System.out.println("環繞前通知=========="); 6 Object obj = joinPoint.proceed(); 7 System.out.println("環繞後通知=========="); 8 return obj; 9 }
@AfterThrowing拋出通知,至關於ThrowAdvice
ide
1 在目標方法出現異常的時候,完成一個操做.得到異常信息. 2 3 @AfterThrowing(value="execution(* cn.itcast.aspectj.demo1.CustomerService+.find(..))",throwing="e") 4 public void afterThrowing(Throwable e){ 5 System.out.println("異常拋出通知========="+e.getMessage()); 6 }
@After 最終final通知,無論是否異常,該通知都會執行
函數
1 在目標方法任何狀況下都會執行的操做.至關於finally中的代碼. 2 3 @After(value="execution(* cn.itcast.aspectj.demo1.CustomerService+.find(..))") 4 public void after(){ 5 System.out.println("最終通知==========="); 6 }
2.2.2 經過配置啓用@AspectJ切面
學習
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="http://www.springframework.org/schema/beans 6 http://www.springframework.org/schema/beans/spring-beans.xsd 7 http://www.springframework.org/schema/aop 8 http://www.springframework.org/schema/aop/spring-aop.xsd"> 9 <!-- 開啓AspectJ自動代理--> 10 <aop:aspectj-autoproxy /> 11 </beans>
2.2.3 在通知中經過value屬性定義切點
測試
經過execution函數,能夠定義切點的方法切入
語法:
execution(<訪問修飾符>?<返回類型><方法名>(<參數>)<異常>)
例如
匹配全部類public方法 execution(public * *(..))
匹配指定包下全部類方法 execution(* cn.itcast.dao.*(..)) 不包含子包
execution(* cn.itcast.dao..*(..)) ..*表示包、子孫包下全部類
匹配指定類全部方法 execution(* cn.itcast.service.UserService.*(..))
匹配實現特定接口全部類方法 execution(* cn.itcast.dao.GenericDAO+.*(..))
匹配全部save開頭的方法 execution(* save*(..))
2.2.4 AspectJ的切入點:
1 統一管理切入點的表達式. 2 @Pointcut(value="execution(* cn.itcast.aspectj.demo1.CustomerService+.find(..))") 3 private void myPointcut1(){} //這個類沒有實際用途, 只是爲了@Pointcut 註解
2.2.6 Aspect和Advisor的區別:
Advisor :傳統的切面.傳統切面通常都是由一個切入點和一個通知的組合.
Aspect :真正意義上的切面.由多個切入點和多個通知的組合.
2.3 Spring AspctJ 基於註解模式的開發
CustomerService.java:
1 public interface CustomerService { 2 3 public void save(); 4 public Integer update(); 5 public void delete(); 6 public void find(); 7 }
CustomerServiceImpl.java:
1 public class CustomerServiceImpl implements CustomerService { 2 3 @Override 4 public void save() { 5 System.out.println("保存客戶..."); 6 } 7 8 @Override 9 public Integer update() { 10 System.out.println("修改客戶..."); 11 return 100; 12 } 13 14 @Override 15 public void delete() { 16 System.out.println("刪除客戶..."); 17 } 18 19 @Override 20 public void find() { 21 System.out.println("查詢客戶..."); 22 int d = 1 / 0; 23 } 24 25 }
MyAspectAnno.java:
1 /** 2 * 自定義切面類: 3 * 4 */ 5 @Aspect 6 public class MyAspectAnno { 7 8 @Before(value="execution(* cn.augmentum.aspectj.demo1.CustomerService+.save(..))") 9 public void before(JoinPoint joinPoint){ 10 System.out.println("前置通知============"+joinPoint); 11 } 12 13 @AfterReturning(value="execution(* cn.augmentum.aspectj.demo1.CustomerService+.update(..))",returning="result") 14 public void afterReturing(Object result){ 15 System.out.println("後置通知============"+result); 16 } 17 18 @Around(value="execution(* cn.augmentum.aspectj.demo1.CustomerService+.delete(..))") 19 public Object around(ProceedingJoinPoint joinPoint) throws Throwable{ 20 System.out.println("環繞前通知=========="); 21 Object obj = joinPoint.proceed(); 22 System.out.println("環繞後通知=========="); 23 return obj; 24 } 25 26 @AfterThrowing(value="MyAspectAnno.myPointcut1()",throwing="e") 27 public void afterThrowing(Throwable e){ 28 System.out.println("異常拋出通知========="+e.getMessage()); 29 } 30 31 @After(value="MyAspectAnno.myPointcut1()") 32 public void after(){ 33 System.out.println("最終通知==========="); 34 } 35 36 @Pointcut(value="execution(* cn.augmentum.aspectj.demo1.CustomerService+.find(..))") 37 private void myPointcut1(){} 38 }
SpringDemo.java 測試類:
1 @RunWith(SpringJUnit4ClassRunner.class) 2 @ContextConfiguration("classpath:applicationContext.xml") 3 public class SpringDemo1 { 4 5 @Resource(name = "customerService") 6 private CustomerService customerService; 7 8 @Test 9 public void demo1() { 10 customerService.save(); 11 customerService.update(); 12 customerService.delete(); 13 customerService.find(); 14 } 15 }
applicationContext.xml 配置文件:
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 http://www.springframework.org/schema/beans/spring-beans.xsd 7 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> 8 9 <!-- 使用註解完成AOP的開發 --> 10 <aop:aspectj-autoproxy/> 11 12 <!-- 目標對象 --> 13 <bean id="customerService" class="cn.augmentum.aspectj.demo1.CustomerServiceImpl"/> 14 15 <!-- 配置切面 --> 16 <bean id="myAspectAnno" class="cn.augmentum.aspectj.demo1.MyAspectAnno"/> 17 </beans>
2.4 Spring AspctJ 基於xml模式的開發
OrderService.java:
1 public class OrderService { 2 public void save(){ 3 System.out.println("保存訂單..."); 4 } 5 public Integer update(){ 6 System.out.println("修改訂單..."); 7 return 200; 8 } 9 public void delete(){ 10 System.out.println("刪除訂單..."); 11 } 12 public void find(){ 13 System.out.println("查詢訂單..."); 14 //int d = 1/ 0; 15 } 16 }
MyAspectXml.java:
1 public class MyAspectXml { 2 3 public void before(){ 4 System.out.println("前置通知==========="); 5 } 6 7 public void afterReturing(Object result){ 8 System.out.println("後置通知==========="+result); 9 } 10 11 public Object around(ProceedingJoinPoint joinPoint) throws Throwable{ 12 System.out.println("環繞前通知=========="); 13 Object obj = joinPoint.proceed(); 14 System.out.println("環繞後通知=========="); 15 return obj; 16 } 17 18 public void afterThrowing(Throwable e){ 19 System.out.println("異常拋出通知========"+e.getMessage()); 20 } 21 22 public void after(){ 23 System.out.println("最終通知=========="); 24 } 25 }
SpringDemo.java 測試類:
1 @RunWith(SpringJUnit4ClassRunner.class) 2 @ContextConfiguration("classpath:applicationContext.xml") 3 public class SpringDemo2 { 4 5 @Resource(name="orderService") 6 private OrderService orderService; 7 8 @Test 9 public void demo1(){ 10 orderService.save(); 11 orderService.update(); 12 orderService.delete(); 13 orderService.find(); 14 } 15 }
applicationContext.xml 配置文件:
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 http://www.springframework.org/schema/beans/spring-beans.xsd 7 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> 8 9 <!-- 配置目標類 --> 10 <bean id="orderService" class="cn.augmentum.aspectj.demo2.OrderService"></bean> 11 12 <!-- 配置切面 --> 13 <bean id="myAspectXml" class="cn.augmentum.aspectj.demo2.MyAspectXml"></bean> 14 15 <!-- AOP的配置 --> 16 <aop:config> 17 <aop:pointcut expression="execution(* cn.augmentum.aspectj.demo2.OrderService.save(..))" id="pointcut1"/> 18 <aop:pointcut expression="execution(* cn.augmentum.aspectj.demo2.OrderService.update(..))" id="pointcut2"/> 19 <aop:pointcut expression="execution(* cn.augmentum.aspectj.demo2.OrderService.delete(..))" id="pointcut3"/> 20 <aop:pointcut expression="execution(* cn.augmentum.aspectj.demo2.OrderService.find(..))" id="pointcut4"/> 21 <aop:aspect ref="myAspectXml"> 22 <aop:before method="before" pointcut-ref="pointcut1"/> 23 <aop:after-returning method="afterReturing" pointcut-ref="pointcut2" returning="result"/> 24 <aop:around method="around" pointcut-ref="pointcut3"/> 25 <aop:after-throwing method="afterThrowing" pointcut-ref="pointcut4" throwing="e"/> 26 <aop:after method="after" pointcut-ref="pointcut4"/> 27 </aop:aspect> 28 </aop:config> 29 </beans>
OK. 到了這裏Spring 基於AOP的開發也總結完了, 學習之路漫漫, 謹以此記錄成長的過程!