AspectJ Load-Time 织入(入门)
程序员文章站
2022-07-02 09:07:07
...
简介
AspectJ 织入方式有 Compile-time weaving
(编译时织入)、 Post-compile weaving
(后编译织入)、 Load-time weaving
(加载时织入)。
其中加载时织入不需要源码,可用于逆向分析。
安装
- 到 http://www.eclipse.org/aspectj/downloads.php 下载最新稳定版,我下载到的版本是
1.8.9
版。 - 双击下载好的jar包,一路 Next,提示安装路径时,我修改为了
D:\aspectj1.8
。 - 配置环境变量
ASPECTJ_HOME
=D:\aspectj1.8
CLASSPATH
=.;%JAVA_HOME%\lib;%JAVA_HOME%\lib\tools.jar;%ASPECTJ_HOME%\lib\aspectjrt.jar
PATH
中添加%ASPECTJ_HOME%\bin
-
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 ,过程如下:
- 新建J2SE项目。
- 项目根目录新建 libs 目录, 将
D:\aspectj1.8\lib\*
复制到libs, 在 libs 目录上右键点击Add as Library...
。 -
src
目录右键New
->Aspect
输入文件名即可编写.aj
文件。 - 有关于
.aj
文件的一些讲解,可以到官方文档( https://eclipse.org/aspectj/doc/released/progguide/index.html 、https://eclipse.org/aspectj/doc/next/progguide/quick.html)查看。