AspectJ 的使用

之前在自定义annotation的时候,发现注解可以在编译的时候 做 动作,就想到了能不能像 sping aop 的 aspectj 那样去切面呢?不过没有思路,就先找AspectJ来学习下.

官网
http://www.eclipse.org/aspectj/
文档
http://www.eclipse.org/aspectj/docs.php

准备:

下载aspect 的 包 http://www.eclipse.org/aspectj/downloads.php
我下载后解压为 有三个目录
bin —- aspect 的命令,如ajc等,
doc —- 文档 包括了example
lib —- 运行的时候,需要使用的jar包(spring也是依赖这些的)

介绍

网上有不少介绍 aspectj 的,不过很多写着和eclipse 集成,这里介绍 直接用 ajc编译的方法来 织入切面代码。

这章的代码来自下载的example

下面两个例子,一个是ltw,一个是tjp,均是入门的例子,
需要一个jar lib/aspectjrt.jar


├─examples
│  ├─ltw
│  │      HelloWorld.java
│  │      README
│  │      Tracing.aj
│  │
│  └─tjp
│          Demo.java
│          files.lst
│          GetInfo.java
│
└─lib
        aspectjrt.jar

先来看 ltw

两个文件
* HelloWorld.java

public class HelloWorld {
    public static void main (String[] args) {
        System.out.println("Hello World!");
    }
}
  • Tracing.aj
public aspect Tracing {

    private pointcut mainMethod () :
        execution(public static void main(String[]));

    before () : mainMethod() {
        System.out.println("> " + thisJoinPoint);
    }

    after () : mainMethod() {
        System.out.println("< " + thisJoinPoint);
    }
}
  • 用ajc来编译,ajc的命令和javac有像
$ ajc -d . -cp ./lib/aspectjrt.jar HelloWorld.java Tracing.aj
  • 编译后,生成两个class ,运行 HelloWorld.class:
$ java -cp ./lib/aspectjrt.jar;. HelloWorld
> execution(void HelloWorld.main(String[]))
Hello World!
< execution(void HelloWorld.main(String[]))

再看另外一个例子 ,examples 的tjp的项目

也是两个java文件,一个files.lst

  • files.lst 内容很简单,就写着 两个java文件
Demo.java
GetInfo.java
  • Demo.java
package tjp;

public class Demo {
    static Demo d;

    public static void main(String[] args){
        new Demo().go();
    }

    void go(){
        d = new Demo();
        d.foo(1,d);
        System.out.println(d.bar(new Integer(3)));
    }

    void foo(int i, Object o){
        System.out.println("Demo.foo(" + i + ", " + o + ")\n");
    }

    String bar (Integer j){
        System.out.println("Demo.bar(" + j + ")\n");
        return "Demo.bar(" + j  + ")";
    }
}
  • GetInfo.java
package tjp;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.reflect.CodeSignature;

aspect GetInfo {

   static final void println(String s){ System.out.println(s); }

   pointcut goCut(): cflow(this(Demo) && execution(void go()));

   pointcut demoExecs(): within(Demo) && execution(* *(..));

   Object around(): demoExecs() && !execution(* go()) && goCut() {
      println("Intercepted message: " +
          thisJoinPointStaticPart.getSignature().getName());
      println("in class: " +
          thisJoinPointStaticPart.getSignature().getDeclaringType().getName());
      printParameters(thisJoinPoint);
      println("Running original method: \n" );
      Object result = proceed();
      println("  result: " + result );
      return result;
   }

   static private void printParameters(JoinPoint jp) {
      println("Arguments: " );
      Object[] args = jp.getArgs();
      String[] names = ((CodeSignature)jp.getSignature()).getParameterNames();
      Class[] types = ((CodeSignature)jp.getSignature()).getParameterTypes();
      for (int i = 0; i < args.length; i++) {
         println("  "  + i + ". " + names[i] +
             " : " +            types[i].getName() +
             " = " +            args[i]);
      }
   }
}

编译(生成class):

...\examples>ajc -cp ../lib/aspectjrt.jar -argfil e tjp/files.lst -d .

运行:

...\examples>java -cp ../lib/aspectjrt.jar;. tjp/Demo

Intercepted message: foo
in class: tjp.Demo
Arguments:
  0. i : int = 1
  1. o : java.lang.Object = tjp.Demo@23fc625e
Running original method:

Demo.foo(1, tjp.Demo@23fc625e)

  result: null
Intercepted message: bar
in class: tjp.Demo
Arguments:
  0. j : java.lang.Integer = 3
Running original method:

Demo.bar(3)

  result: Demo.bar(3)
Demo.bar(3)

说明:

  • 看起来,spring的语法和aspectj的语法差不多,s但spring 只是用了语法,在切面技术,是用代理的方式来处理.,参考:https://www.ibm.com/developerworks/cn/java/j-lo-springaopcglib/.
  • 更多的功能和内容,会要看看aspectj的语法.
  • springaop用得不少,但aspecj这种要换编译器的,在什么场景会好使用呢?有点好奇
  • 呼应开头,annotation貌似没在aspectj基础上使用,看来技术线不一样
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值