1. 程式人生 > >[Spring框架]Spring AOP基礎入門總結二:Spring基於AspectJ的AOP的開發.

[Spring框架]Spring AOP基礎入門總結二:Spring基於AspectJ的AOP的開發.

work 復制代碼 配置文件 exec dao tool ont pda nbsp

前言:
在上一篇中: [Spring框架]Spring AOP基礎入門總結一. 中 我們已經知道了一個Spring AOP程序是如何開發的, 在這裏呢我們將基於AspectJ來進行AOP 的總結和學習.

一, AspectJ的概述:

AspectJ是一個面向切面的框架,它擴展了Java語言。AspectJ定義了AOP語法所以它有一個專門的編譯器用來生成遵守Java字節編碼規範的Class文件。

Spring為了簡化自身的AOP的開發,將AspectJ拿過來作為Spring自身一個AOP的開發.

二, Spring AspectJ開發實例

2.1 開發所需jar包
技術分享圖片


2.2 AspectJ 註解開發規範

2.2.1 @AspectJ提供不同的通知類型

@Before 前置通知,相當於BeforeAdvice
  在執行目標方法之前完成一個操作,獲得到切入點信息.

@AfterReturning 後置通知,相當於AfterReturningAdvice

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

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>
技術分享圖片

[Spring框架]Spring AOP基礎入門總結二:Spring基於AspectJ的AOP的開發.