使用AspectJ在Android中实现Aop

原创 2016年07月24日 16:36:45

开题

上一篇文章Android Aop预研中介绍了Aop的各种实现方式,并且在最后提到,选择AspectJ作为合适的开发方式。这篇文章通过我自己编写的一个例子,来说明AspectJ的使用。

首先要声明,使用AspectJ进行Android的Aop开发,早有例子,一篇写得很好的文章是Aspect Oriented Programming in Android,有需要的朋友可以看译文【翻译】Android中的AOP编程

可以这样说,上面的文章将我所要介绍的大部分关于AOP的内容都包含了,而且讲解得很明晰易懂,建议在阅读本文之前,先读上面的文章。

另外,本文不对AspectJ相关的基本语法做介绍,在阅读本文前,最好对AspectJ有基本的了解,由于网上的朋友,对这些内容有大量的介绍,我也不去做这些重复的工作。推荐文章为深入理解Android之AOP

最后,还需要提醒大家,本文项目代码中,使用到自定义gradle插件的相关知识,这里也不赘述,推荐文章为在 Android Studio 中自定义 Gradle 插件


本文的用意

看到此处的朋友可以会问,既然上面的几篇文章,将你要讲的东西都说完了,我们直接去看不就成了。答案是,的确是这样的。那么我写这篇文章的用意是什么呢?
首先主要是一个总结的目的,再者本文参考的主要项目代码为JakeWharton大神的Hugo。Hugo是一个非常容易使用、易扩展的Aop例子,上面的【翻译】Android中的AOP编程
。也提到这个项目,是比文章介绍的项目更加完整的。

但是Hugo使用到的不止Aspect的知识,并且自定义了一个gradle插件方便项目里有ajc编译器进行编译(因为一个app必然会依赖其他lib,我们可以在lib和app中都使用aop,但是都要使用ajc对其编译,gradle插件的好处就是将编译设置抽出,成为一个app,lib都可以使用的模块)。如果没有上面三篇文章的基础,是难以理解Hugo项目的。

因此,我对Hugo项目进行了一些探究,将其aspectj和gradle模块分离,模仿其方式实现了一个gradle插件,并且实现了Aop。
本文只对项目代码做简单介绍,需要具体了解的朋友,在阅读完三篇文章以后,可以下载项目代码直接运行,查看效果。

使用AspectJ

使用AspectJ的方法很简单,首先是定义一个DebugLog注解

import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.CONSTRUCTOR;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.CLASS;

@Target({TYPE, METHOD, CONSTRUCTOR}) @Retention(CLASS)
public @interface DebugLog {
}

接下来就是使用AspectJ的方式,其设置PointCut(什么?你不知道PointCut?说明你没有看上面推荐的文章。。。)

@Aspect
public class Hugo {
    //带有DebugLog注解的所有类
    @Pointcut("within(@com.example.aoplib.DebugLog *)")
    public void withinAnnotatedClass() {}

    //在带有DebugLog注解的所有类,除去synthetic修饰的方法
    @Pointcut("execution(!synthetic * *(..)) && withinAnnotatedClass()")
    public void methodInsideAnnotatedType() {}

    //在带有DebugLog注解的所有类,除去synthetic修饰的构造方法
    @Pointcut("execution(!synthetic *.new(..)) && withinAnnotatedClass()")
    public void constructorInsideAnnotatedType() {}

    //在带有DebugLog注解的方法
    @Pointcut("execution(@com.example.aoplib.DebugLog * *(..)) || methodInsideAnnotatedType()")
    public void method() {}

   //在带有DebugLog注解的构造方法
    @Pointcut("execution(@com.example.aoplib.DebugLog *.new(..)) || constructorInsideAnnotatedType()")
    public void constructor() {}
    ....
}

上面代码的注释中,已经说明了每个PointCut的意义,也就是说,AspectJ会去寻找带有@DebugLog注解的类,或者带有@DebugLog注解的方法和构造方法。

接着是定义Advice

@Around("method() || constructor()")
    public Object logAndExecute(ProceedingJoinPoint joinPoint) throws Throwable {
        //执行方法前,做些什么
        enterMethod(joinPoint);

        long startNanos = System.nanoTime();
        //执行原方法
        Object result = joinPoint.proceed();
        long stopNanos = System.nanoTime();
        long lengthMillis = TimeUnit.NANOSECONDS.toMillis(stopNanos - startNanos);
        //执行方法后,做些什么
        exitMethod(joinPoint, result, lengthMillis);

        return result;
    }

这些代码,和Hugo中的一模一样,我将其抽取,构成一个简单的library,叫做aoplib,看下图:
这里写图片描述



Gradle

从上图可以看到,buildsrc中,包含了我自定义的一个gradle插件,其内容和Hugo项目中的hugo-plugin一致。
app或者lib需要添加ajc编译的内容,只需要apply这个插件就可以了,不必每个模块都编写相同的gradle代码。

apply plugin: ‘com.hc.gradle’



测试

定义Aop以后,我们可以在app文件夹下,也就是我们的Android项目中使用,并且,我们也可以在自己创建的module中使用,如上图,testlib就是我创建的一个test模块,它依赖aoplib,因此可以使用aop定义的注解,并且使用了我自定义的插件,也不需要自己写Ajc部分内容。

这个test模块中,我对AspectJ的使用范围作了一些测试,有兴趣的朋友可以看看。


写在最后

最后贴上项目代码AopDemo,欢迎大家fork和star,本项目代码可以看出对Hugo的梳理,如果对Hugo代码感到阅读困难,可以查看我自认为更加清晰的代码。

版权声明:本文为博主原创文章,转载请注明出处。

看AspectJ在Android中的强势插入

什么是AOPAOP是Aspect Oriented Programming的缩写,即『面向切面编程』。它和我们平时接触到的OOP都是编程的不同思想,OOP,即『面向对象编程』,它提倡的是将功能模块化,...
  • x359981514
  • x359981514
  • 2017年01月16日 09:58
  • 8724

Android基于AOP的非侵入式监控之——AspectJ实战

本博文的目的不是详细的介绍AspectJ的细节,而是最近项目用到了AspectJ,因此对其作了一些使用和重要概念上的总结。 相信很多做过Web的同学对[AspectJ](https://eclipse...
  • woshimalingyi
  • woshimalingyi
  • 2016年05月24日 10:45
  • 12856

Android中使用AspectJ

aop学习 深入理解Android之AOP什么是AOPAOP是Aspect Oriented Programming的缩写,即『面向切面编程』。它和我们平时接触到的OOP都是编程的不同思想,OOP,即...
  • vonnie_jade
  • vonnie_jade
  • 2017年04月02日 21:01
  • 246

利用AspectJ实现Android端非侵入式埋点

前言 AspectJ是什么 AspectJ中的几个名词术语解释 AOP编程的具体使用场景 注入代码的时机 几个常用的工具和类库 为什么选择AspectJ 举个栗子 创建注解 创建用于控制监听的类 封装...
  • cmder1000
  • cmder1000
  • 2017年04月16日 10:20
  • 1173

AndroidStudio中 AspectJ 基础使用 简介

AOP(Aspect Oriented Programming)切面编程在处理一些与业务逻辑无关,但在很多地方又不得不添加相关逻辑代码,可以很好的解决相关问题,比如在Android中有些地方需要打LO...
  • u012238268
  • u012238268
  • 2016年09月02日 17:37
  • 2705

Android AOP 之AspectJ(二)

环境搭建:
  • shaohuazuo
  • shaohuazuo
  • 2016年09月19日 14:36
  • 821

Android中的AOP编程之AspectJ实战实现数据埋点

文章背景 最近在给某某银行做项目的时,涉及到了数据埋点,性能监控等问题,那我们起先想到的有两种方案,方案之一就是借助第三方,比如友盟、Bugly等,由于项目是部署在银行的网络框架之内的,所以该方案不可...
  • XiNanHeiShao
  • XiNanHeiShao
  • 2017年07月01日 22:55
  • 2479

深入理解Android之AOP

深入理解Android之AOP格式更加精美的PDF版请到:http://vdisk.weibo.com/s/z68f8l0xTgCLK 下载一、闲谈AOP大家都知道OOP,即ObjectOriente...
  • Innost
  • Innost
  • 2015年10月24日 19:48
  • 47657

Android 基于AOP监控之——AspectJ使用指南

AspectJ的使用核心就是它的编译器,它就做了一件事,将AspectJ的代码在编译期插入目标程序当中,运行时跟在其它地方没什么两样,因此要使用它最关键的就是使用它的编译器去编译代码ajc。ajc会构...
  • woshimalingyi
  • woshimalingyi
  • 2016年05月27日 22:01
  • 8309

Android 开发中使用 AOP

大家对AOP应该都不陌生, 就算没有用过也肯定听说过. 用过或了解过Java AOP的同学应该都知道AspectJ的大名. 因为AspectJ与java程序完全兼容,几乎是无缝关联, 所以只需要做一些...
  • l2show
  • l2show
  • 2017年03月19日 14:19
  • 1665
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:使用AspectJ在Android中实现Aop
举报原因:
原因补充:

(最多只允许输入30个字)