使用AspectJ實現AOP

AOP專門用於處理系統中分佈於各個模塊(不一樣方法)中的交叉關注點的問題,在JavaEE應用中,經常經過AOP來處理一些具備橫切性質的系統級服務,如事務管理、安全檢查、緩存、對象池管理等,AOP已經成爲一種很是經常使用的解決方案。java

在學習SpringAOP以前,咱們先來簡單看看AspectJ。編程

AspectJ是一個基於Java語言的AOP框架,提供了強大的AOP功能,其餘不少AOP框架都借鑑或採納其中的一些思想。因爲Spring3.0的AOP與AspectJ進行了很好的集成,所以掌握AspectJ是學習SpringAOP的基礎。緩存

AspectJ主要包括兩個部分:安全

部分 描述
第一部分

定義瞭如何表達、定義AOP編程中的語法規範,經過這套規範,咱們能夠方便地用AOP來解決Java語言中存在的交叉關注點問題。框架

另外一部分 工具部分,包括編譯器、調試工具等。
package com.ant;

public class Hello{
	
	public static void main(String[] args){
		Hello hello = new Hello();
		hello.sayHello();
	}
	
	public void sayHello(){
		System.out.println("Hello AspectJ!");
	} 
}
package com.ant;

public aspect TxAspect{

	void around():call(void Hello.sayHello()){
		System.out.println("Transaction start...");
		proceed();
		System.out.println("Transaction end...");
	}
}

package com.ant;

public aspect LogAspect{
	
	pointcut logPointcut():execution(void Hello.sayHello());
	
	after():logPointcut(){
		System.out.println("log...");
	}
}

咱們利用javap反編譯生成的Hello.class,能夠發現它不是由Hello.java編譯獲得的,該Hello.class文件內新增了不少內容------這代表AspectJ在編譯時已經加強了Hello.class的功能,所以AspectJ一般被稱爲編譯時加強的AOP框架。工具

Compiled from "Hello.java"
public class com.ant.Hello {
  public com.ant.Hello();
    Code:
       0: aload_0       
       1: invokespecial #8                  // Method java/lang/Object."<init>":()V
       4: return        

  public static void main(java.lang.String[]);
    Code:
       0: new           #1                  // class com/ant/Hello
       3: dup           
       4: invokespecial #17                 // Method "<init>":()V
       7: astore_1      
       8: aload_1       
       9: astore_2      
      10: aload_2       
      11: invokestatic  #56                 // Method com/ant/TxAspect.aspectOf:()Lcom/ant/TxAspect;
      14: aconst_null   
      15: invokestatic  #60                 // Method sayHello_aroundBody1$advice:(Lcom/ant/Hello;Lcom/ant/TxAspect;Lorg/aspectj/runtime/internal/AroundClosure;)V
      18: return        

  public void sayHello();
    Code:
       0: getstatic     #24                 // Field java/lang/System.out:Ljava/io/PrintStream;
       3: ldc           #30                 // String Hello AspectJ!
       5: invokevirtual #32                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
       8: goto          20
      11: astore_1      
      12: invokestatic  #67                 // Method com/ant/LogAspect.aspectOf:()Lcom/ant/LogAspect;
      15: invokevirtual #70                 // Method com/ant/LogAspect.ajc$after$com_ant_LogAspect$1$9fd5dd97:()V
      18: aload_1       
      19: athrow        
      20: invokestatic  #67                 // Method com/ant/LogAspect.aspectOf:()Lcom/ant/LogAspect;
      23: invokevirtual #70                 // Method com/ant/LogAspect.ajc$after$com_ant_LogAspect$1$9fd5dd97:()V
      26: return        
    Exception table:
       from    to  target type
           0    11    11   Class java/lang/Throwable

  private static final void sayHello_aroundBody0(com.ant.Hello);
    Code:
       0: aload_0       
       1: invokevirtual #18                 // Method sayHello:()V
       4: return        

  private static final void sayHello_aroundBody1$advice(com.ant.Hello, com.ant.TxAspect, org.aspectj.runtime.internal.AroundClosure);
    Code:
       0: getstatic     #24                 // Field java/lang/System.out:Ljava/io/PrintStream;
       3: ldc           #44                 // String Transaction start...
       5: invokevirtual #32                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
       8: aload_2       
       9: astore_3      
      10: aload_0       
      11: invokestatic  #62                 // Method sayHello_aroundBody0:(Lcom/ant/Hello;)V
      14: getstatic     #24                 // Field java/lang/System.out:Ljava/io/PrintStream;
      17: ldc           #52                 // String Transaction end...
      19: invokevirtual #32                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
      22: return        
}

與AspectJ相對的還有另一種AOP框架,它們不須要在編譯時對目標類進行加強,而是運行時生成目標類的代理類,該代理類要麼與目標類實現相同的接口,要麼是目標類的子類------總之,代理類都對目標類進行了加強處理,前者是JDK動態代理的處理策略,後者是cglib代理的處理策略。SpringAOP以建立動態代理的方式來生成代理類,底層既可以使用JDK動態代理,也可採用cglib代理。學習

相關文章
相關標籤/搜索