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代理。学习