AspectJ构建模型-Build-time-weave and Load-time-weave

AspectJ目前支持编译时织入。可以支持源代码、class文件、jar文件等形式。AJC可以对输入的文件产生织入后的文件(class\jar文件)。然后就可以文件部署到正式的运行环境中,同时还需要添加aspectjrt.jar文件。
aspectjrt包含了joinpoint、signature、等各种可以被用户访问的类型、
编译时织--会在编译时,就会报出一些错误。
而LTW会在载入虚拟机时,编织代码时,才会报出错误。

1、构建时源代码编织

在这种情况下,编织器只会接受源代码(普通语法或者注解形式)的形式进行织入。编译器会自动产生二进制代码形式。

额外知识点:Ajc编译器可以根据命令行中输入的多个源代码目录进行编译。然后将结果输入到一个目录下。同时在编译时也会提供多个选择配置项,用于显示编织信息例如:-showWeaverInfo   用于显示AspectJ是怎样编织源代码和切面的;-Xlint 用于打印一些可能存在的潜在性的错误。当然具体都有哪些选项在aspectj的官网上都可以找到。具体可以参考。

实际上,源代码织入利用了二进制代码织入。当两者(*.java与*.aj)都是源代码形式时,ajc都会现将两者编译成二进制代码的形式,然后才会将进行合并成*.class 文件。*.aj文件必须用ajc编译器进行编译,因为javac不会识别这样的语法。

二进制代码织入对于编织aspectj注解构建出来的切面和业务类是特别有用的。因为可以使用javac去编译利用注解形式书写出来的切面,然后利用使用二进制代码编织去产生自己想要的最终系统结果(例如一个jar包)。我们可以使用javac去编译基于注解的切面和业务类代码。但是不能编译aj源代码。aj源代码只能有ajc去编译。然后双方都编译完成后,就可以将两者作为输入的二进制代码格式去编织出最后的系统jar包。

2、载入时织入(Load-time weaving)

载入时织入实际上是二进制织入的扩展。LTW也跟二进制织入一样都是以二进制代码作为输入。不同的一点就是载入时织入没有明确织入步骤(所谓的明确的织入步骤--编译源代码--》ajc----》业务final jar package).相应的,而是由vm在载入class文件进入虚拟机内存时进行织入。因此这也就是为什么称之为LTW的原因。载入时织入使用了java虚拟的Java virtual machine Tool interface 功能(以后简称为JVMTI)。JVMTI机制是在java5之后引入的。JVMTI机制允许在载入一个类时,可以对载入步骤进行拦截。载入时织入器(Load-time weaver)实际上就是一个JVMTI代理,在载入二进制代码时,对二进制代码进行修改--即织入。在进行拦截时,不会立即去扫面类路径下所有的切面,而是通过一个配置文件的形式去配置切面。配置文件的通常放置到/Meta-INF/aop.xml文件中。当然也可以在jvm通过配置项去显示配置文件的个数以及位置。下面详细介绍JVMTI结合LTW的使用:

1、命令(不言自明,不必多说)

java –javaagent /aspectjweaver.jar [other-option]

2、JVM初始化/META-INF/下的aop.xml 文件,如果有多个文件的话,那么织入器代理就会进行合并。用这个合并后的文件,作为织入的切面和类的参考依据。

3、置入器代理注册自己在类加载过程中的关注点(也可以称之为事件,即当类加载发生了到某个时间点时就会通知织入器代理),当被通知时,就会对载入的当前类进行织入修改,当然前提是有对应的切入点与之对应。

重点1-怎样书写aop.xml文件(即配置LTW)?

前提:除了aop.xml之外所有的输入都是经过javac或者ajc编译好的jar和class文件。基于这种xml的配置方式不用再编译现有系统的前提下,就可以实现切面的注入。

 

编译时织入消耗了编译时间,而LTW消耗了载入class文件的时间。

你可能感兴趣的:(AspectJ构建模型-Build-time-weave and Load-time-weave)