1.aop是什么
那AOP通俗点来讲是啥呢?
举个例子:
现在假设系统中有 3 段完全相似的代码,这些代码通常会采用“复制”、“粘贴”方式来完成,通过这种“复制”、“粘贴”方式开发出来的软件。
可能有的读者已经发现了这种做法的不足之处:如果有一天,这部分相似的代码段需要修改,那是不是要打开 3 个地方的代码进行修改?
如果不是 3 个地方包含这段代码,而是 100 个地方,甚至是 1000 个地方包含这段代码段,那会是什么后果?
针对该情况我们会做优化:抽出这部分代码,封装在一个公共类的方法里,提供其他地方调用。
当这块功能需要调整时,只要修改一个地方即可,不管整个系统中有多少地方调用了该方法,程序无须修改这些地方,只需修改被调用的方法即可——通过这种方式,大大降低了软件后期维护的复杂度。
读到这里你会发现,我们还没讲到AOP...下面我们再升级下场景:
如果 3 个地方需要同样新调一个方法,我们的做法会是在这三个地方各自额外补充新方法的调用。
如果不是 3 个地方新调用,而是 100 个地方,甚至是 1000 个地方来新调用,这样做的工作量也不小啊!
我们希望有一种特殊的方法:我们只要定义该方法,无须在方法 1、方法 2、方法 3 中显式调用它,系统会“自动”执行该特殊方法。
上面想法听起来很神奇,甚至有一些不切实际,但其实是完全可以实现的,实现这个需求的技术就是 AOP。
AOP 专门用于处理系统中分布于各个模块(不同方法)中的交叉关注点的问题。
在 Java EE 应用中,常常通过 AOP 来处理一些具有横切性质的系统级服务,如事务管理、安全检查、缓存、对象池管理等,AOP 已经成为一种非常常用的解决方案。
咳咳,AOP概念正式版:
AOP(Aspect Orient Programming),作为面向对象编程的一种补充,广泛应用于处理一些具有横切性质的系统级服务,如事务管理、安全检查、缓存、对象池管理等。
AOP 实现的关键就在于 AOP 框架自动创建的 AOP 代理,AOP 代理则可分为静态代理和动态代理两大类,其中静态代理是指使用 AOP 框架提供的命令进行编译,从而在编译阶段就可生成 AOP 代理类,因此也称为编译时增强;
而动态代理则在运行时借助于 JDK 动态代理、CGLIB 等在内存中“临时”生成 AOP 动态代理类,因此也被称为运行时增强。
2.有什么作用
通过AOP,可以在指定位置执行对应流程。这样就可以将一些横向的功能抽离出来形成一个独立的模块,然后在指定位置插入这些功能。
3.怎么用
下面我们整理下普通的Java代码中怎么实现AOP:
有两种方式实现AOP切面,一种是原生SDK实现,一种是基于三方包cglib。
(Java的有3种代理模式:静态代理、动态代理、cglib代理。)
代理·比较
那么这两种方式有什么相同点和区别呢?
相同点是都使用了代理模式。
不同点是前者使用了接口代理,后者使用了继承代理。
JDK代理类是接口代理,是因为它继承了proxy这个类,java是单继承的,jdk代理类通过调用处理器中的invoke方法来实现动态代理的目的。
cglib是子类代理,cglib性能要比jdk好,但创建代理对象时,jdk比cglib效率高。
JDK的动态代理有一个限制,就是使用动态代理的对象必须实现一个或多个接口,如果想代理没有实现接口的类,就可以使用Cglib实现。Cglib是一个强大的高性能的代码生成包,它可以在运行期扩展java类与实现java接口。它广泛的被许多AOP的框架使用它广泛的被许多AOP的框架使用,例如Spring AOP和synaop,为他们提供方法的interception(拦截)。
Cglib包的底层是通过使用一个小而块的字节码处理框架ASM来转换字节码并生成新的类。不鼓励直接使用ASM,因为它要求你必须对JVM内部结构包括class文件的格式和指令集都很熟悉。
总结
1、AOP 是用来处理一些具有横切性质的系统级服务。
2、java代理有三种:静态代理、动态代理、cglib代理。其中AOP涉及到的是后两者。
3、JDK代理是接口代理,cglib是继承代理(Spring aop就是用该框架)。