欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

AspectJ Load-Time 织入(入门)

程序员文章站 2022-07-02 09:07:13
...

简介

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
  4. 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.html 、https://eclipse.org/aspectj/doc/next/progguide/quick.html)查看。