AOP与AspectJ的关系
- AspectJ简介
- 两者关系
- 引用关系
- 织入(Weaving)
- 依赖
- 代理模式
- aspectj静态代理
- jdk动态代理
- cglib的动态代理
AspectJ简介
AspectJ是java编程语言的无缝的面向方面的扩展,一整套完整的切面增强解决方案,包含自己的语法,编译器,最终可以在java代码的字节码中植入切面代码。
AspectJ 是静态代理的增强,所谓的静态代理就是 AOP 框架会在编译阶段生成 AOP 代理类,因此也称为编译时增强。
AspectJ 是 Java 语言的一个 AOP 实现,其主要包括两个部分:
- 第一个部分定义了如何表达、定义 AOP 编程中的语法规范,通过这套语言规范,我们可以方便地用 AOP 来解决 Java 语言中存在的交叉关注点问题
- 另一个部分是工具部分,包括编译器、调试工具等。
AspectJ 是最早、功能比较强大的 AOP 实现之一,对整套 AOP 机制都有较好的实现,很多其他语言的 AOP 实现,也借鉴或采纳了 AspectJ 中很多设计。在 Java 领域,AspectJ 中的很多语法结构基本上已成为 AOP 领域的标准。
两者关系
AOP面向切面编程是一种编程思想,是对OOP面向对象编程的一种补充。对于AOP这种编程思想,很多框架都进行了实现。Spring就是其中之一,可以完成面向切面编程。而AspectJ也实现了AOP的功能,且其实现方式更为简捷,使用更为方便,而且还支持注解式开发。所以,Spring又将AspectJ对于AOP的实现也引入到了自己的框架中。
引用关系
我们可以看到Spring Aop中引入了aspectjweaver这个包,下面说明一下作用和原因。
织入(Weaving)
AspectJ 作为 AOP 编程的完全解决方案,提供了三种织入时机,分别为
- compile-time:编译期织入,在编译的时候一步到位,直接编译出包含织入代码的 .class 文件
- post-compile:编译后织入,增强已经编译出来的类,如我们要增强依赖的 jar 包中的某个类的某个方法
- load-time:在 JVM 进行类加载的时候进行织入
组装方面来创建一个被通知对象。这可以在编译时完成(例如使用AspectJ编译器),也可以在运行时完成。Spring和其他纯Java AOP框架一样,在运行时完成织入。
依赖
所以Spring AOP只需要依赖aspectjweaver包来负责织入就可以,不需要引入AspectJ的编译器。
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.13</version>
</dependency>
代理模式
aspectj静态代理
原理:在编译期织入代码,编译成class文件
优点:可以增强任何类,任何方法,包括(final,static修饰)
缺点:需要使用aspecj提供的Ajc编译器来编译Aj文件。
jdk动态代理
使用jdk的动态代理来增强接口实现类
原理:使用Proxy类的newProxyInstance方法运行期通过反射动态的生成代理对象
优点:不需要修改具体的业务代码,动态的增强方法,降低耦合性。
缺点:代理的对象必须有接口实现。
cglib的动态代理
可以对jdk的动态代理作为补充
原理:以创建目标类的子类来生成动态代理对象。
优点:不需要修改具体的业务代码,动态的增强方法,降低耦合性。
缺点:不能对final修饰的类,final修饰的方法或static的方法进行代理