使用的方法大概有这几种: 调用命令直接编译(直接使用ajc命令或者调用java -jar aspectjtools.jar) 使用IDE集成的ajc编译器编译 使用自动化构建工具的插件编译 其实2,3两点的本质都是使用 ", ajc$initFailureCause); } return ajc$perSingletonInstance; } public static boolean hasAspect = null; } private static void ajc$postClinit() { ajc$perSingletonInstance = new AjAspect 因此我们仍然需要用ajc来处理: ! 加载时织入(LTW) 前两种织入方法都依赖于ajc的编译工具,LTW却通过java agent机制在内存中操作类文件,可以不需要ajc的支持做到动态织入。
AspectJ 分为 编译时织入:通过 ajc 用编译生成 class 文件 编译后织入:已经 javac 生成 class 文件后,通过处理 class 文件得到新的织入后的 class 文件 加载时织入 (LTW):通过java agent机制在内存中操作类文件,可以不需要ajc的支持做到动态织入。 ", ajc$initFailureCause); } return ajc$perSingletonInstance; } public static boolean hasAspect () { return ajc$perSingletonInstance ! = null; } private static void ajc$postClinit() { ajc$perSingletonInstance = new AjAspect
AspectJ是什么 AspectJ实际上是对AOP编程思想的一个实践,它不是一个新的语言,它就是一个代码编译器(ajc),在Java编译器的基础上增加了一些它自己的关键字识别和编译方法。 因此,ajc也可以编译Java代码。 4、在主build.gradle(Module:app)中添加也要添加AspectJ依赖,同时编写build脚本,添加任务,目的就是为了建立两者的通信,使得IDE使用ajc编译代码。 $tjp_0; private static final JoinPoint.StaticPart ajc$tjp_1; Button btn_test; Button btn_test2; static { ajc$preClinit(); } private static void ajc$preClinit() { Factory localFactory
安装好的目录结构为: bin:存放了 aj、aj5、ajc、ajdoc、ajbrowser 等命令,其中 ajc 命令最常用,它的作用类似于 javacdoc:存放了 AspectJ 的使用说明、参考手册 after():logPointcut(){ System.out.println("记录日志 ..."); } } 编译SayHelloService 执行命令 ajc SayHelloService.java LogAspect.java 生成 SayHelloService.class 执行命令 java SayHelloService 输出 Hello AspectJ 记录日志 ajc.exe 可以理解为 javac.exe 命令,都用于编译 Java 程序,区别是 ajc.exe 命令可识别 AspectJ 的语法;我们可以将 ajc.exe 当成一个增强版的 javac.exe 命令.执行 ajc命令后的 SayHelloService.class 文件不是由原来的 SayHelloService.java 文件编译得到的,该 SayHelloService.class 里新增了打印日志的内容
使用 AspectJ 时需要使用专门的编译器 ajc。 (这个是针对当前项目的设置,所以可以放心修改): 有如下几个需要修改的点: 首先修改编译器为 ajc。 $postClinit(); } catch (Throwable var1) { ajc$initFailureCause = var1; } ajc$aroundClosure) { System.out.println("开启事务"); try { ajc$around$org_javaboy_demo_p2 public static boolean hasAspect() { return ajc$perSingletonInstance !
安装好的目录结构为: bin:存放了 aj、aj5、ajc、ajdoc、ajbrowser 等命令,其中 ajc 命令最常用,它的作用类似于 javac doc:存放了 AspectJ 的使用说明、参考手册 after():logPointcut(){ System.out.println("记录日志 ..."); } } 3、编译SayHelloService 执行命令 ajc SayHelloService.java LogAspect.java 生成 SayHelloService.class 执行命令 java SayHelloService 输出 Hello AspectJ 记录日志 ajc.exe 可以理解为 javac.exe 命令,都用于编译 Java 程序,区别是 ajc.exe 命令可识别 AspectJ 的语法;我们可以将 ajc.exe 当成一个增强版的 javac.exe 命令.执行 *ajc命令后的 SayHelloService.class 文件不是由原来的 SayHelloService.java 文件编译得到的,该 SayHelloService.class 里新增了打印日志的内容
{ if (isPause) { string json = "{'status':'3'}"; ajc_SDKCall.CallStatic } void OnApplicationFocus(bool isFocus) { if (isFocus) { if (ajc_SDKCall = null){ string json = "{'status':'1'}"; ajc_SDKCall.CallStatic("uaLifeCycle ",json); json = "{'status':'2'}"; ajc_SDKCall.CallStatic("uaLifeCycle } } void OnApplicationQuit() { string json = "{'status':'5'}"; ajc_SDKCall.CallStatic
成功安装了AspectJ之后,将会在E:\Java\AOP\aspectj1.6路径下(AspectJ的安装路径)看到如下文件结构: bin:该路径下存放了aj、aj5、ajc、ajdoc、ajbrowser 等命令,其中ajc命令最常用,它的作用类似于javac,用于对普通Java类进行编译时增强。 打开DOS窗口,输入ajc命令,可以看到输出ajc命令的所有信息,即可知安装和环境变量配置成功: 使用AspectJ 接下来我们模拟一个普通程序: UserService: package com.mybry.aop.service 再用ajc –d *.java命令编译执行: 太开心了,搞定了! 假如此时客户又要求在每个方法中增加事物处理呢?
安装好的目录结构为: bin:存放了 aj、aj5、ajc、ajdoc、ajbrowser 等命令,其中 ajc 命令最常用,它的作用类似于 javac doc:存放了 AspectJ 的使用说明、参考手册 after():logPointcut(){ System.out.println("记录日志 ..."); } } 编译 SayHelloService: 执行命令 ajc SayHelloService.java LogAspect.java 生成 SayHelloService.class 执行命令 java SayHelloService 输出 Hello AspectJ 记录日志 ajc.exe 可以理解为 javac.exe 命令,都用于编译 Java 程序,区别是 ajc.exe 命令可识别 AspectJ 的语法;我们可以将 ajc.exe 当成一个增强版的 javac.exe 命令.执行 ajc命令后的 SayHelloService.class 文件不是由原来的 SayHelloService.java 文件编译得到的,该 SayHelloService.class 里新增了打印日志的内容
Monitor("textClick") public void textClick(View view) { JoinPoint var3 = Factory.makeJP(ajc this, view, var3, MonitorAspect.aspectOf(), (ProceedingJoinPoint)var3); } static { ajc "-bootclasspath", project.android.bootClasspath.join(File.pathSeparator)] log.debug "ajc
使用AspectJ的编译器编译 ajc -d . public void ajc$around$com_listenzhangbin_aop_TxAspect$1$f54fe983(AroundClosure ajc$aroundClosure) { System.out.println("开始事务 ..."); ajc$around$com_listenzhangbin_aop_TxAspect$1$f54fe983proceed (ajc$aroundClosure); System.out.println("事务结束 ..."); } 从Aspect编译后的class文件可以更明显的看出执行的逻辑。
将编译器改为 Ajc,接着设置Ajc的安装目录,选择到aspectjtools.jar,同时,一定要将Delegate to Javac选项打钩,这个代理设置的作用只对指定的项目进行Ajc编译,其他的项目还是用默认的 如果不勾选这个代理选项,则全部项目都使用Ajc编译器编译,可能会导致编译错误。 ? 指定需要使用Ajc编译的项目 分别为spring-aop及spring-aspects添加Facets属性。
使用AspectJ的编译器编译 ajc -d . Hello.java TxAspect.aj 编译完成之后再运行这个Hello类,可以看到以下输出: 开始事务 ... hello 事务结束 ... Aspect编译后的class文件 public void ajc$around$com_listenzhangbin_aop_TxAspect$1$f54fe983(AroundClosure ajc $aroundClosure) { System.out.println("开始事务 ..."); ajc$around$com_listenzhangbin_aop_TxAspect $1$f54fe983proceed(ajc$aroundClosure); System.out.println("事务结束 ..."); } 从Aspect编译后的class文件可以更明显的看出执行的逻辑
使用AspectJ的编译器编译 ajc -d . Hello.java TxAspect.aj 编译完成之后再运行这个Hello类,可以看到以下输出 开始事务 ... hello 事务结束 ... public void ajc$around$com_listenzhangbin_aop_TxAspect$1$f54fe983(AroundClosure ajc$aroundClosure) { System.out.println("开始事务 ..."); ajc$around$com_listenzhangbin_aop_TxAspect$1$f54fe983proceed (ajc$aroundClosure); System.out.println("事务结束 ..."); } 从Aspect编译后的class文件可以更明显的看出执行的逻辑。
import org.aspectj.bridge.IMessage import org.aspectj.bridge.MessageHandler import org.aspectj.tools.ajc.Main "-bootclasspath", project.android.bootClasspath.join(File.pathSeparator)] log.debug "ajc import org.aspectj.bridge.IMessage import org.aspectj.bridge.MessageHandler import org.aspectj.tools.ajc.Main "-bootclasspath", project.android.bootClasspath.join(File.pathSeparator)] log.debug "ajc
使用AspectJ的编译器编译 ajc -d . Hello.java TxAspect.aj 编译完成之后再运行这个Hello类,可以看到以下输出 开始事务 ... hello 事务结束 ... public void ajc$around$com_listenzhangbin_aop_TxAspect$1$f54fe983(AroundClosure ajc$aroundClosure) { System.out.println("开始事务 ..."); ajc$around$com_listenzhangbin_aop_TxAspect$1$f54fe983proceed (ajc$aroundClosure); System.out.println("事务结束 ..."); } 从Aspect编译后的class文件可以更明显的看出执行的逻辑。
import org.aspectj.bridge.IMessage import org.aspectj.bridge.MessageHandler import org.aspectj.tools.ajc.Main "-bootclasspath", project.android.bootClasspath.join(File.pathSeparator)] log.debug "ajc import org.aspectj.bridge.IMessage import org.aspectj.bridge.MessageHandler import org.aspectj.tools.ajc.Main "-bootclasspath", project.android.bootClasspath.join(File.pathSeparator)] log.debug "ajc
AspectJ的使用核心就是它的编译器,它就做了一件事,将AspectJ的代码在编译期插入目标程序当中,运行时跟在其它地方没什么两样,因此要使用它最关键的就是使用它的编译器去编译代码ajc。 ajc会构建目标程序与AspectJ代码的联系,在编译期将AspectJ代码插入被切出的PointCut中,达到AOP的目的。 要理解AspectJ,就需要理解AspectJ提出的几个新的概念。 由于aspectj编译时需要用到ajc编译器,为了使 Aspectj能在Android上运行,将aspect模块的代码注入app中,需要使用gradle插件完成编译。 2,在gintonic中添加AspectJ依赖,同时编写build脚本,添加任务,使得IDE使用ajc作为编译器编译代码,然后把该Module添加至主工程Module中。 import org.aspectj.bridge.IMessage import org.aspectj.bridge.MessageHandler import org.aspectj.tools.ajc.Main
ajbrowser 等命令,其中 ajc 命令最常用,它的作用类似于 javac,用于对普通 Java 类进行编译时增强。 正如前面提到的,Java 无法识别 TxAspect.java 文件的内容,所以我们要使用 ajc.exe 命令来编译上面的 Java 程序。 接下来执行如下命令进行编译: ajc -d . Hello.java TxAspect.java 我们可以把 ajc.exe 理解成 javac.exe 命令,都用于编译 Java 程序,区别是 ajc.exe 命令可识别 AspectJ 的语法;从这个意义上看 ,我们可以将 ajc.exe 当成一个增强版的 javac.exe 命令。
class AbstractAspectJAdvisorFactory implements AspectJAdvisorFactory { private static final String AJC_MAGIC = "ajc$"; private static final Class<?