AOP: 切面编程:静态AOP、动态AOP

  • Post author:
  • Post category:其他


1:AOP的概念

1)相对于OOP面向对象概念,AOP面向切面编程,是指为了将本身无法联系的两个类,通过某张方式将其联系起来

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

2:AOP实现方式

2.1 :静态AOP

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

2.1.1 AspectJ

属于静态AOP 它是在编译时进行增强,会在编译时期将 AOP逻辑织入到代码中,同时由于是在编译器织入,所以它的优点时不影响运行时性能,缺点就是不够灵活。

AspectJ提供了

两套

强大的机制:

第一套是

切面语法

。就是网上随便一搜的

AspectJ使用方法

,它把

决定是否使用切面的权利

还给了切面。就是说在写切面的时候就可以决定哪些类的哪些方法会被代理,从而

从逻辑上

不需要侵入业务代码。

由于这套语法实在是太有名,导致很多人都误以为AspectJ就是这一套切面语法,其实不然。

第二套是

织入工具

。上面介绍的切面语法能够让切面从逻辑上与业务代码解耦,但是从操作上来讲,当JVM运行业务代码的时候,他无从得知旁边还有个类想横插一刀。解决思路就是在编译期(或者类加载期)我们优先考虑一下切面代码,并将切面代码通过某种形式插入到业务代码中,这样业务代码不就知道自己被“切”了么?这种思路的一个实现就是

aspectjweaver

,就是这里的

织入工具


AspectJ

提供了两套对切面的描述方法:

一种就是我们常见的

基于java注解

切面描述的方法,这种方法兼容java语法,写起来十分方便,不需要IDE的额外语法检测支持。

另外一种是

基于aspect文件

的切面描述方法,这种语法本身并不是java语法,因此写的时候需要IDE的插件支持才能进行语法检查。

2.1.2 :AbstractProcessor

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

2.2 : 动态AOP

2.2.1 : JDK动态代理

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

2.2.2 : 动态字节码生成

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

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

2.2.3 :自定义类加载器

在运行期,目标加载前,将切面逻辑加到目标字节马里,如: javassist

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

2.2.4: ASM

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

3:AOP应用举例

3.1 : AspectJ 使用,请移步查看下面文章


Android AOP切面编程框架 : AspectJ_hongwen_yul的博客-CSDN博客_android aop框架



版权声明:本文为u013620306原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。