Skip to content

Latest commit

 

History

History
51 lines (29 loc) · 2.79 KB

AOP.md

File metadata and controls

51 lines (29 loc) · 2.79 KB

AOP

AOP(Aspect Oriented Programing),面向切面编程。 是OOP(Object Oriented Programing)面向对象编程的延续。

在OOP思想中,我们会把问题划分为各个模块,如语言、表情等。
在划分这些模块的过程中,也会出现一些共同特征(如埋点)。它的逻辑被分散到了各个模块,导致了代码复杂度提高,可复用性降低。

而AOP,就是将各个模块中的通用逻辑抽离出来。 我们将这些逻辑视为Aspect(切面),然后动态地把代码插入到类的指定方法、指定位置中。

一句话概括: 在运行时,动态的将代码切入到类的指定方法、指定位置上的编程思想就是面相切面的编程。

一般而言,我们管切入到指定类指定方法的代码片段称为切面,而切入到哪些类、哪些方法则叫切入点。有了AOP,我们就可以把几个类共有的代码,抽取到一个切片中,等到需要时再切入对象中去,从而改变其原有的行为。

AOP的实现方式

静态AOP

在编译器,切面直接以字节码的形式编译到目标字节码文件中。

  1. AspectJ
    AspectJ属于静态AOP,它是在编译时进行增强,会在编译时期将AOP逻辑织入到代码中。

由于是在编译器织入,所以它的优点是不影响运行时性能,缺点是不够灵活。

  1. AbstractProcessor
    自定义一个AbstractProcessor,在编译期去解析编译的类,并且根据需求生成一个实现了特定接口的子类(代理类)

动态AOP

  1. JDK动态代理
    通过实现InvocationHandler接口,可以实现对一个类的动态代理,通过动态代理可以生成代理类,从而在代理类方法中,在执行被代理类方法前后,添加自己的实现内容,从而实现AOP。

  2. 动态字节码生成
    在运行期,目标类加载后,动态构建字节码文件生成目标类的子类,将切面逻辑加入到子类中,没有接口也可以织入,但扩展类的实例方法为final时,则无法进行织入。比如Cglib

CGLIB是一个功能强大,高性能的代码生成包。它为没有实现接口的类提供代理,为JDK的动态代理提供了很好的补充。通常可以使用Java的动态代理创建代理,但当要代理的类没有实现接口或者为了更好的性能,CGLIB是一个好的选择。

  1. 自定义类加载器
    在运行期,目标加载前,将切面逻辑加到目标字节码里。如:Javassist

Javassist是可以动态编辑Java字节码的类库。它可以在Java程序运行时定义一个新的类,并加载到JVM中;还可以在JVM加载时修改一个类文件。

  1. ASM
    ASM可以在编译期直接修改编译出的字节码文件,也可以像Javassit一样,在运行期,类文件加载前,去修改字节码。