Aspect 入门

本贴最后更新于 2349 天前,其中的信息可能已经时移世易

AspectJ 是 eclipse 上托管的一个 AOP 的编程语言

官方示例

快速入门

安装

  1. 官方页面上下载 最新的安装包,目前是 aspectj-1.8.12.jar
  2. java -jar aspectj-1.8.12.jar,会出现提示页面,一路 NEXT 即可
  3. 配置环境变量 CLASSPATH 和 PATH
# aspectj1.8
export PATH=$PATH:/Users/abeffect/Green/AspectJ/aspectj1.8/bin
export CLASSPATH="/Users/abeffect/Green/AspectJ/aspectj1.8/lib/aspectjrt.jar:$CLASSPATH"
  1. 测试:aj, aj5, ajbrowser, ajc, ajdoc 命令均已可用

示例

  1. 安装目录下有 doc/examples/ 目录,进入此目录
  2. 执行 命令
ajc -argfile telecom/billing.lst

可以看到目录 doc/examples/telecom 下生成了一系列的 class 文件

运行示例

java -cp /Users/abeffect/Green/AspectJ/aspectj1.8/lib/aspectjrt.jar:. telecom/BillingSimulation

结果


... Billing simulation 2 ...

jim calls mik...
[new local connection from Jim(650) to Mik(650)]
mik accepts...
connection completed
jim hangs up...
connection dropped
Jim(650) has been connected for 201 seconds and has a bill of 603
Mik(650) has been connected for 201 seconds and has a bill of 0
Crista(415) has been connected for 0 seconds and has a bill of 0
mik calls crista...
[new long distance connection from Mik(650) to Crista(415)]
crista accepts...
connection completed
crista hangs up...
connection dropped
Jim(650) has been connected for 201 seconds and has a bill of 603
Mik(650) has been connected for 351 seconds and has a bill of 1500
Crista(415) has been connected for 150 seconds and has a bill of 0

通过 jadx 确认结果

jadx 是将二进制 class 文件反编译成 java 文件的反编译工具

mac 下安装 jadx

brew install jadx

使用

jadx-gui

通过 procyon 反编译

jdk8 的反编译工具,推荐 procyon

原理

ajc 是用 java 开发的一个 java 编译器,使用指定的 aspectj 文件来处理 java 源文件,编译成对应的 class 文件。

编译时加载 aspect

使用 ajc,来实现编译时加载 aspect

ajc 是类似于 javac 的编译工具

编译一个 aspect 和一个文件

ajc -d $DES_DIR MyClass.java MyAspect.java

编译器将产生两个.class 文件

编译一个 aspect 和一系列文件

建立 appname.lst 文件,内容如下

com/abeffect/MyClass.java
com/abeffect/MyAspect.java
com/abeffect/AnotherClass.java
com/abeffect/AnotherAspect.java

使用 ajc 编译

ajc -argfile appname.lst -d $DES_DIR

编译一个 aspect 和一个 jar 文件

假定 aspect 文件为 MyAspect.java, jar 文件为 myApp.jar。

下面的命令会使用 MyAspect.java 来处理 myApp.jar 中的每一个文件,结果 class 文件保存在 $DES_DIR 中

ajc -inpath myApp.jar path/to/MyAspect.java -d $DES_DIR

下面的命令会把结果保存在新的 jar 文件中

ajc -inpath myApp.jar path/to/MyAspect.java -outjar myNewApp.jar

运行时加载 aspect

使用 aj,来实现运行时加载 aspect

aj 类似于 java,是运行 jar 包的工具

命令示例

#!/bin/sh
export ASPECTPATH=path/to/aspect
export CLASSPATH=xxx

aj MyClassMain

遗憾的时,遇到了异常

Error occurred during initialization of VM
java.lang.ExceptionInInitializerError
	at org.aspectj.weaver.WeaverMessages.<clinit>(WeaverMessages.java:18)
	at org.aspectj.weaver.bcel.ClassPathManager.addPath(ClassPathManager.java:86)
	at org.aspectj.weaver.bcel.ClassPathManager.<init>(ClassPathManager.java:66)
	at org.aspectj.weaver.bcel.BcelWorld.<init>(BcelWorld.java:285)
	at org.aspectj.weaver.tools.WeavingAdaptor.init(WeavingAdaptor.java:176)
	at org.aspectj.weaver.tools.WeavingAdaptor.<init>(WeavingAdaptor.java:109)
	at org.aspectj.weaver.loadtime.WeavingURLClassLoader.<init>(WeavingURLClassLoader.java:75)
	at org.aspectj.weaver.loadtime.WeavingURLClassLoader.<init>(WeavingURLClassLoader.java:52)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
	at java.lang.SystemClassLoaderAction.run(ClassLoader.java:2211)
	at java.lang.SystemClassLoaderAction.run(ClassLoader.java:2195)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.lang.ClassLoader.initSystemClassLoader(ClassLoader.java:1456)
	at java.lang.ClassLoader.getSystemClassLoader(ClassLoader.java:1436)
Caused by: java.lang.IllegalStateException: recursive invocation
	at java.lang.ClassLoader.initSystemClassLoader(ClassLoader.java:1450)
	at java.lang.ClassLoader.getSystemClassLoader(ClassLoader.java:1436)
	at java.util.ServiceLoader.loadInstalled(ServiceLoader.java:568)
	at java.util.ResourceBundle.<clinit>(ResourceBundle.java:376)
	at org.aspectj.weaver.WeaverMessages.<clinit>(WeaverMessages.java:18)
	at org.aspectj.weaver.bcel.ClassPathManager.addPath(ClassPathManager.java:86)
	at org.aspectj.weaver.bcel.ClassPathManager.<init>(ClassPathManager.java:66)
	at org.aspectj.weaver.bcel.BcelWorld.<init>(BcelWorld.java:285)
	at org.aspectj.weaver.tools.WeavingAdaptor.init(WeavingAdaptor.java:176)
	at org.aspectj.weaver.tools.WeavingAdaptor.<init>(WeavingAdaptor.java:109)
	at org.aspectj.weaver.loadtime.WeavingURLClassLoader.<init>(WeavingURLClassLoader.java:75)
	at org.aspectj.weaver.loadtime.WeavingURLClassLoader.<init>(WeavingURLClassLoader.java:52)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
	at java.lang.SystemClassLoaderAction.run(ClassLoader.java:2211)
	at java.lang.SystemClassLoaderAction.run(ClassLoader.java:2195)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.lang.ClassLoader.initSystemClassLoader(ClassLoader.java:1456)
	at java.lang.ClassLoader.getSystemClassLoader(ClassLoader.java:1436)

查看了一些资料,aj 是通过修改 class loader 的方式来实现的,可能存在兼容性问题,推荐使用 上述的 “编译一个 aspect 和一个 jar 文件”方式。

进一步阅读

  1. aspectJ 简单例子
  2. Android 基于 AOP 监控之——AspectJ 构建指南
  3. 从 Gradle 使用 Ant
  4. AspectJ Cookbook 中文版
  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3168 引用 • 8207 回帖

相关帖子

回帖

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...