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 编程的完全解决方案,提供了三种织入时机,分别为

  1. compile-time:编译期织入,在编译的时候一步到位,直接编译出包含织入代码的 .class 文件
  2. post-compile:编译后织入,增强已经编译出来的类,如我们要增强依赖的 jar 包中的某个类的某个方法
  3. 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的方法进行代理