1. 程式人生 > >Spring_Spring與AOP_AspectJ基於註解的AOP實現

Spring_Spring與AOP_AspectJ基於註解的AOP實現

編碼 ride yar exception end clas junit www 其中

一、AspectJ、Spring與AOP的關系

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

Spring又將AspectJ的對於AOP的實現引入到自己的框架中。

在Spring中使用AOP開發時,一般使用AspectJ的實現方式。

二、AspectJ的通知類型

  1. 前置通知
  2. 後置通知
  3. 環繞通知
  4. 異常通知
  5. 最終通知

三、AspectJ的切入點表達式


技術分享圖片

表達式中加【】的部分表示可省略部分 ,個部分用空格分開。在其中可以使用以下符號:

技術分享圖片

execution(* * ..service.*.*(..))

指定所有包下的service子包下所有類(接口)中所有方法為切入點

execution(* *..ISomeService.*(..))

指定所有包下的ISomeService接口中所有方法為切入點

三、AspectJ的開發環境


導入2個Jar包

spring-framework-3.0.2.RELEASE-dependencies\org.aspectj\com.springsource.org.aspectj.weaver\1.6.8.RELEASE

技術分享圖片

技術分享圖片

技術分享圖片

技術分享圖片

技術分享圖片

四、AspectJ基於註解的AOP實現

1、前置通知

技術分享圖片
1 //主業務接口
2 public interface ISomeService {
3 //目標方法 4 void doFirst(); 5 String doSecond(); 6 void doThird(); 7 8 }
ISomeService 技術分享圖片
 1 public class SomeServiceImpl implements ISomeService {
 2 
 3     @Override
 4     public void doFirst() {
 5         // TODO Auto-generated method stub
 6         System.out.println("執行doFirst()方法");
7 } 8 9 @Override 10 public String doSecond() { 11 // TODO Auto-generated method stub 12 System.out.println("執行doSecond()方法"); 13 return "abcde"; 14 } 15 16 @Override 17 public void doThird() { 18 // TODO Auto-generated method stub 19 System.out.println("執行doThird()方法"); 20 } 21 22 }
SomeServiceImpl 技術分享圖片
 1 import org.aspectj.lang.JoinPoint;
 2 import org.aspectj.lang.annotation.Aspect;
 3 import org.aspectj.lang.annotation.Before;
 4 
 5 @Aspect  //表示當前類為切面
 6 public class MyAspect {
 7    @Before("execution(* *..ISomeService.doFirst(..))")
 8    public void  before(){
 9        System.out.println("執行前置通知方法");
10    }
11    
12    @Before("execution(* *..ISomeService.doFirst(..))")
13    public void  before(JoinPoint jp){
14        System.out.println("執行前置通知方法 jp="+jp);
15    }
16     
17 }
MyAspect 技術分享圖片
 1 import org.junit.Test;
 2 import org.springframework.context.ApplicationContext;
 3 import org.springframework.context.support.ClassPathXmlApplicationContext;
 4 
 5 public class MyTest {
 6 
 7     @Test
 8     public void test01() {
 9         //創建容器對象
10         String resource = "com/bjpowernode/annotation/applicationContext.xml";
11         ApplicationContext ac=new ClassPathXmlApplicationContext(resource);
12        
13         ISomeService service=(ISomeService) ac.getBean("someService");
14         service.doFirst();
15         System.out.println("--------------------");
16         service.doSecond();
17         System.out.println("--------------------");
18         service.doThird();
19     }
20 
21 }
MyTest 技術分享圖片
 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" xsi:schemaLocation="
 5         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     <!-- 註冊切面 -->
10     <bean id="myAspect" class="com.bjpowernode.annotation.MyAspect"></bean>
11      
12      <!-- 註冊目標對象 -->
13      <bean id="someService" class="com.bjpowernode.annotation.SomeServiceImpl"></bean>
14       
15      <!--   註冊AspectJ的自動代理 -->
16      <aop:aspectj-autoproxy/>  
17 </beans>
ApplicationContext

輸出:

技術分享圖片
執行前置通知方法
執行前置通知方法 jp=execution(void com.bjpowernode.annotation.ISomeService.doFirst())
執行doFirst()方法
--------------------
執行doSecond()方法
--------------------
執行doThird()方法
output

2.後置通知

技術分享圖片
 1   @AfterReturning("execution(* *..ISomeService.doSecond(..))")
 2    public void myAfterReturning(){
 3        System.out.println("執行後置通知方法");
 4        
 5    }
 6    
 7    @AfterReturning(value="execution(* *..ISomeService.doSecond(..))",returning="result")
 8    public void myAfterReturning(Object result){
 9        System.out.println("執行後置通知方法 result="+result);
10        
11    }
MyAspect

3、環繞通知

技術分享圖片
1    @Around("execution(* *..ISomeService.doSecond(..))")
2    public Object myAround(ProceedingJoinPoint pjp) throws Throwable{
3        System.out.println("執行環繞通知方法,目標方法執行之前");
4        //執行目標方法
5        Object result = pjp.proceed();
6        System.out.println("執行環繞通知方法,目標方法執行之後");
7     return result;
8        
9    }
MyAspect

輸出:

技術分享圖片
1 執行環繞通知方法,目標方法執行之前
2 執行doSecond()方法
3 執行環繞通知方法,目標方法執行之後
output

4、異常通知

技術分享圖片
1  @AfterThrowing("execution(* *..ISomeService.doThird(..))")
2    public void myAfterThrowing(){
3       System.out.println("執行異常通知方法");  
4    }
MyAspect 技術分享圖片
1   @AfterThrowing(value="execution(* *..ISomeService.doThird(..))",throwing="ex")
2    public void myAfterThrowing(Exception ex){
3       System.out.println("執行異常通知方法ex="+ex.getMessage());  
4    }
MyAspect 技術分享圖片
1 執行異常通知方法ex=/ by zero
output

5、最終通知

技術分享圖片
1  @After("execution(* *..ISomeService.doThird(..))")
2    public void myAfter(){
3       System.out.println("執行最終通知方法");  
4    }
View Code

五、定義切入點

定義了一個切入點,叫doThirdPointcut()

1  @After("doThirdPointcut()")
2    public void myAfter(){
3       System.out.println("執行最終通知方法");  
4    }
5    //定義了一個切入點,叫doThirdPointcut()
6    @Pointcut("execution(* *..ISomeService.doThird(..))")
7    public void doThirdPointcut(){}
8 }

Spring_Spring與AOP_AspectJ基於註解的AOP實現