说下我对AOP的理解:AOP是给程序添加统一功能的一种技术。在代码层面上来说,AOP就是在必要的业务代码中织入业务无关的、统一的代码的一种技术。在实现AOP的时候,通常努力争取的目标是对业务代码无侵入或是低侵入。
平时用得比较多的是Spring中的AOP实现,还有一些比如Spring中的shiro权限验证,@Cachable注解等在某种程度上也可以认为是AOP。在Spring AOP之外还有很多其他的实现方式。
在了解AOP实现方案之前有必要看一下java类编译加载的过程。
java类编译的过程如下:
.java文件 –> 编译 –> .class文件 –> 载入虚拟机
在虚拟机中加载使用类的过程如下:
装载 –> 验证 –> 准备 –> 解析 –> 初始化 –> 使用 –>卸载
上面所述的过程中,通常可以在编译和装载这两个环节向原始代码中织入AOP代码。
编译环节织入代码往往需要定制的编译器,如使用AspectJ的时候,就可以通过AspectJ的编译器ajc来完成AOP代码的织入。这个环节织入的代码class文件中就有体现。
装载环节实现代码织入的方式比较多,大致有这么几种:
- 基于JVMTI Agent方式;
- 替换默认的系统类加载器;
- 使用自定义类加载器;
- 使用动态代理。
jvmtgi方式是一种侵入度很低的形式,只需要在启动时添加一些特定的启动参数,如javaagent。我曾经写过一个java方法运行时间统计程序:jspy-agent,就是用这种方式在在java方法中织入计时代码。这种方式需要对字节码文件进行操作,目前的字节码操作框架有asm、bcel、javassist等。
使用自定义类加载器替换默认系统类加载器也只需要添加一个启动参数:-Djava.system.class.loader=com.your.CustomClassLoader。前提是需要自定义一个类加载器。当然自定义类加载器也不只是有这一种使用方式。
关于动态代理,目前用的比较多的就是JDK动态代理和CGlib了,相关的资料一抓一大把,不说了。
大体上就是这些了。不过还有一个问题,想和大家一起想想:java设计模式中的代理模式、装饰模式是不是也算是AOP的一种实现呢?
参考文档:
SpringAOP织入:https://blog.csdn.net/wuliusir/article/details/32916419
JVMTI Agent:https://www.ibm.com/developerworks/cn/java/j-lo-jpda2/
#############
发表评论