- AspectJ是一个代码生成工具(Code Generator)。
- AspectJ语法就是用来定义代码生成规则的语法。您如果使用过Java Compiler Compiler (JavaCC),您会发现,两者的代码生成规则的理念惊人相似。
- AspectJ有自己的语法编译工具,编译的结果是Java Class文件,运行的时候,classpath需要包含AspectJ的一个jar文件(Runtime lib)。
- ....
public class Speaker
{
public void speak()
{
System.out.println("[Speaker] bla bla ");
}
public static void main(String[] args)
{
Speaker speaker = new Speaker();
speaker.speak();
}
}
public aspect AspectObserver
{
pointcut speakerSpeak():
call(void *Speaker.speak());
before() : speakerSpeak() {
System.out.println("[AspectObserver] speaker is about to speak!");
}
after() returning() : speakerSpeak() {
System.out.println("[AspectObserver] speaker has completed his speech!");
}
}
[Speaker] bla bla
[AspectObserver] speaker has completed his speech!
// Jad home page: [url]http://www.kpdus.com/jad.html[/url]
// Decompiler options: packimports(3) radix(10) lradix(10)
// Source File Name: Speaker.java
package test.aspectj;
import java.io.PrintStream;
// Referenced classes of package test.aspectj:
// AspectObserver
public class Speaker
{
public Speaker()
{
}
public void speak()
{
System.out.println("[Speaker] bla bla ");
}
public static void main(String args[])
{
Speaker speaker = new Speaker();
AspectObserver.aspectOf().ajc$before$test_aspectj_AspectObserver$1$b2b6354();
speaker.speak();
AspectObserver.aspectOf().ajc$afterReturning$test_aspectj_AspectObserver$2$b2b6354();
}
}
// Jad home page: [url]http://www.kpdus.com/jad.html[/url]
// Decompiler options: packimports(3) radix(10) lradix(10)
// Source File Name: AspectObserver.aj
package test.aspectj;
import java.io.PrintStream;
import org.aspectj.lang.NoAspectBoundException;
public class AspectObserver
{
public AspectObserver()
{
}
void ajc$pointcut$$speakerSpeak$44()
{
}
public void ajc$before$test_aspectj_AspectObserver$1$b2b6354()
{
System.out.println("[AspectObserver] speaker is about to speak!");
}
public void ajc$afterReturning$test_aspectj_AspectObserver$2$b2b6354()
{
System.out.println("[AspectObserver] speaker has completed his speech!");
}
public static AspectObserver aspectOf()
{
if(ajc$perSingletonInstance == null)
throw new NoAspectBoundException("test_aspectj_AspectObserver", ajc$initFailureCause);
else
return ajc$perSingletonInstance;
}
public static boolean hasAspect()
{
return ajc$perSingletonInstance != null;
}
private static void ajc$postClinit()
{
ajc$perSingletonInstance = new AspectObserver();
}
private static Throwable ajc$initFailureCause;
public static final AspectObserver ajc$perSingletonInstance;
static
{
try
{
ajc$postClinit();
}
catch(Throwable throwable)
{
ajc$initFailureCause = throwable;
}
}
}
[Speaker] bla bla
[AspectObserver] speaker has completed his speech!
二、AspectJ发现一些文件含有aspect的定义,在这个例子里,就是AspectObserver的定义;这些aspect就是代码生成规则。
三、AspectJ根据这些aspect代码生成规则,修改添加你的源代码。在这个例子里,源码是修改成怎样了?比较一下反编译后的代码和源码便知。
四、AspectJ读取AspectObserver的定义,发现了一个pointcut--speakerSpeak();这个pointcut的定义是call(void *Speaker.speak()),表示所有对Speaker类的speak方法的执行点。
五、AspectJ继续读取AspectObserver的定义,发现了一个before(),这在AspectJ中叫做Advice。Advice允许你在某个类的方法的调用之前或调用之后,加入另外的代码。加入的代码是什么?比较一下反编译后的代码和源码吧。 AspectJ继续读取AspectObserver的定义.
{
Speaker speaker = new Speaker();
AspectObserver.aspectOf().ajc$before$test_aspectj_AspectObserver$1$b2b6354();//多了这行
speaker.speak();
AspectObserver.aspectOf().ajc$afterReturning$test_aspectj_AspectObserver$2$b2b6354();//多了这行
}
- AspectJ是一个代码生成工具(Code Generator)。
- AspectJ语法就是用来定义代码生成规则的语法。