JAVA面向方面编程 - 运行时方面编织和类加载时间方面编织

Che*_*tan 3 java aop spring-aop

我来了一篇关于AOP的文章,在那里提到Aspect编织可以在编译时,类加载时间和运行时期间发生.

在java中,我可以想象,而不是理解编译时编程方面实际上会如何发生.代理类在类编译过程中生成(在项目中启用了方面).生成的字节码将具有代理代码.

但我仍然想知道在类加载时间编织和运行时编织期间究竟(实际)发生了什么.代理类是在加载类时生成的吗?方面库是否在.class(编译时)文件中添加任何编程指令以生成代理类?

kri*_*aex 6

Spring AOP实际上将Java动态代理用于接口,如果需要,还使用cglib用于非接口类型.它只适用于Spring Beans.为所有与所谓的切入点匹配的方法自动生成代理.这是在布线期间完成的.

然而,AspectJ不需要甚至不使用代理,它直接生成字节代码,编码到现有的字节代码中.AspectJ功能更强大,可以做的不仅仅是方法拦截.

  • 对于编译时编织(CTW),这是由AspectJ编译器ajc完成的.您可以使用Java注释样式定义方面(通常称为@AspectJ语法),而不是本机AspectJ语法(它是Java的超集).在这种情况下,您可以使用javac编译方面,并在单独的构建步骤中使用aspect weaver.结果基本相同.在这两种情况下,在运行时期间,您需要一个小的AspectJ运行时库,以使方面按预期工作.
  • CTW和LTW(加载时间编织)之间的区别在于编织步骤被推迟到类加载时间.为了完成这项工作,您需要在JVM命令行上使用名为AspectJ weaver的Java代理库.Java代理在加载普通应用程序类之前启动,因此可以影响类加载并根据需要检测加载的字节代码.分析工具或类似工具也使用此方法.
  • 显然LTW不能使用源代码而是使用类文件,即AspectJ可以将其方面代码编织到任何常规Java类文件中.这也可以在运行时之前完成,即你可以将方面代码编织到一个你没有源代码的外部库中,创建一个新的修改版本,以便每次加载库时节省LTW的时间.这通常被称为二元编织.通过一些额外的知识,甚至可以将方面代码编织到JDK中,即通过创建包括方面代码的修改的rt.jar.但这不是你通常做的事情,我只是想提一下这是可能的.