AspectJ Load-Time 织入(入门)

简介

AspectJ 织入方式有 Compile-time weaving (编译时织入)、 Post-compile weaving (后编译织入)、 Load-time weaving (加载时织入)。

其中加载时织入不需要源码,可用于逆向分析。

安装

  1. http://www.eclipse.org/aspectj/downloads.php 下载最新稳定版,我下载到的版本是 1.8.9 版。
  2. 双击下载好的jar包,一路 Next,提示安装路径时,我修改为了D:\aspectj1.8
  3. 配置环境变量
    ASPECTJ_HOME = D:\aspectj1.8

CLASSPATH = .;%JAVA_HOME%\lib;%JAVA_HOME%\lib\tools.jar;%ASPECTJ_HOME%\lib\aspectjrt.jar
PATH 中添加 %ASPECTJ_HOME%\bin

  1. D:\aspectj1.8\doc\examples\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);
    }
}

上面是官方自带的例子,HelloWorld 是被织入的程序,Tracing.aj 相当于配置文件。

执行命令 javac HelloWorld.java 将 HelloWorld.java 编译为 HelloWorld.class

执行命令 ajc -outjar Tracing.jar -outxml Tracing.aj 将 Tracing.aj 编译为 Tracing.jar

使用命令 java HelloWorld 运行 HelloWorld 类,输出 Hello World!

使用命令 aj5 -classpath "Tracing.jar;%CLASSPATH%" HelloWorld 运行 HelloWorld 类,结果为

> execution(void HelloWorld.main(String[]))
Hello World!
< execution(void HelloWorld.main(String[]))

自己根据官方的例子写了个小demo:

// com/lanyus/Main.java
package com.lanyus;

/**
 * Created by ilanyu on 2016/10/31.
 */
public class Main {

    public int add(int x, int y) {
        return x + y;
    }

    public static void main(String[] args) {
        System.out.println(new Main().add(1, 2));
    }
}

// Tracing1.aj
public aspect Tracing1 {
    private pointcut mainMethod():
            execution(public static void main(String[]));

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

    after (): mainMethod() {
        System.out.println("< " + thisJoinPoint);
    }

    private pointcut addMethod():
            execution(public int add(int, int));
    before (): addMethod() {
        System.out.println("> " + thisJoinPoint);
        System.out.println("args[0]: " + thisJoinPoint.getArgs()[0].toString());
        System.out.println("args[1]: " + thisJoinPoint.getArgs()[1].toString());
    }

    after (): addMethod() {
        System.out.println("< " + thisJoinPoint);
    }
}

分别编译后

使用 java com.lanyus.Main 结果为 3

使用 aj5 -classpath "trancing1.jar;%CLASSPATH%" com.lanyus.Main 结果为

> execution(void com.lanyus.Main.main(String[]))
> execution(int com.lanyus.Main.add(int, int))
args[0]: 1
args[1]: 2
< execution(int com.lanyus.Main.add(int, int))
3
< execution(void com.lanyus.Main.main(String[]))

小提示

可使用 *.. 通配符, 如

private pointcut main1Method () :
    execution(* *.*(..));

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

after () : main1Method() {
    System.out.println("< " + thisJoinPoint);
}

文档在这 https://eclipse.org/aspectj/doc/next/progguide/quick-typePatterns.html

编写 .aj 文件

编写 .aj 文件时可以使用 IntelliJ IDEA ,过程如下:

  1. 新建J2SE项目。
  2. 项目根目录新建 libs 目录, 将D:\aspectj1.8\lib\*复制到libs, 在 libs 目录上右键点击Add as Library...
  3. src目录右键 New -> Aspect 输入文件名即可编写 .aj 文件。
  4. 有关于 .aj 文件的一些讲解,可以到官方文档( https://eclipse.org/aspectj/doc/released/progguide/index.htmlhttps://eclipse.org/aspectj/doc/next/progguide/quick.html)查看。

标签: none

评论已关闭