android架构师之路——AOP讲解

AOP简介

AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。

1、aop中的术语语

Joinpoint(连接点)所谓连接点是指那些被拦截到的点
Pointcut(切入点)所谓切入点是指我们要对哪些 Joinpoint 进行拦截的定义
Advice(通知/增强)所谓通知是指拦截到 Joinpoint 之后所要做的事情就是通知
Introduction(引介)引介是一种特殊的通知在不修改类代码的前提下, Introduction 可以在运行期为类 动态地添加一些方法或 Field
Target(目标对象)代理的目标对象
Weaving(织入)是指把增强应用到目标对象来创建新的代理对象的过程. AspectJ 采用编译期织入和类装在期织入
Proxy(代理)一个类被 AOP 织入增强后,就产生一个结果代理类
Aspect(切面)是切入点和通知(引介)的结合

 

2、advice分类

Before前置通知, 在目标执行之前执行通知
After后置通知, 目标执行后执行通知
Around环绕通知, 在目标执行中执行通知, 控制目标执行时机
AfterReturning后置返回通知, 目标返回时执行通知
AfterThrowing异常通知, 目标抛出异常时执行通知

 

3、切入点指示符

execution用于匹配方法执行的连接点
within用于匹配指定类型内的方法执行
this用于匹配当前AOP代理对象类型的执行方法;注意是AOP代理对象的类型匹配,这样就可能包括引入接口也类型匹配
target用于匹配当前目标对象类型的执行方法;注意是目标对象的类型匹配,这样就不包括引入接口也类型匹配
args用于匹配当前执行的方法传入的参数为指定类型的执行方法
@within用于匹配所以持有指定注解类型内的方法
@target用于匹配当前目标对象类型的执行方法,其中目标对象持有指定的注解
@args用于匹配当前执行的方法传入的参数持有指定注解的执行
@annotation用于匹配当前执行方法持有指定注解的方法

 

aspectj使用

此项目是给予aspect1.9.4版本开发  minSdkVersion必须大于24

1、app.gradle添加依赖

dependencies {
   implementation 'org.aspectj:aspectjrt:1.9.4'
}

2、project.gradle添加依赖

    dependencies {
        classpath 'com.android.tools.build:gradle:3.3.2'
        classpath 'org.aspectj:aspectjtools:1.9.4'
    }

3、app.gradle添加任务,添加在最外层

import org.aspectj.bridge.IMessage
import org.aspectj.bridge.MessageHandler
import org.aspectj.tools.ajc.Main

final def log = project.logger
final def variants = project.android.applicationVariants

//在构建工程时,执行编辑
variants.all { variant ->
    if (!variant.buildType.isDebuggable()) {
        log.debug("Skipping non-debuggable build type '${variant.buildType.name}'.")
        return;
    }

    JavaCompile javaCompile = variant.javaCompile
    javaCompile.doLast {
        String[] args = ["-showWeaveInfo",
                         "-1.9",
                         "-inpath", javaCompile.destinationDir.toString(),
                         "-aspectpath", javaCompile.classpath.asPath,
                         "-d", javaCompile.destinationDir.toString(),
                         "-classpath", javaCompile.classpath.asPath,
                         "-bootclasspath", project.android.bootClasspath.join(File.pathSeparator)]
        log.debug "ajc args: " + Arrays.toString(args)

        MessageHandler handler = new MessageHandler(true);
        new Main().run(args, handler);
        for (IMessage message : handler.getMessages(null, true)) {
            switch (message.getKind()) {
                case IMessage.ABORT:
                case IMessage.ERROR:
                case IMessage.FAIL:
                    log.error message.message, message.thrown
                    break;
                case IMessage.WARNING:
                    log.warn message.message, message.thrown
                    break;
                case IMessage.INFO:
                    log.info message.message, message.thrown
                    break;
                case IMessage.DEBUG:
                    log.debug message.message, message.thrown
                    break;
            }
        }
    }
}

4、新建interface  BehaviorTrance.java

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface BehaviorTrance {
    String value();
}

5、新建 BehaviorTraceAspect.java

需要将execution中的com.example.aoptest.aspectj.annotation.BehaviorTrance换成你自己的包名

@Aspect
public class BehaviorTraceAspect {

    @Pointcut("execution(@com.example.aoptest.aspectj.annotation.BehaviorTrance *  *(..))")
    public void methodAnnottatedWithBehaviorTrace() {
    }

    @Before("methodAnnottatedWithBehaviorTrace()")
//    @After("methodAnnottatedWithBehaviorTrace()")
    public void before(JoinPoint point) {
        MethodSignature methodSignature = (MethodSignature) point.getSignature();
        String className = methodSignature.getDeclaringTypeName();
        String methodName = methodSignature.getName();
        String value = methodSignature.getMethod().getAnnotation(BehaviorTrance.class).value();
        Log.d("zkq", String.format("%s功能:%s类的%s方法执行了",value, className, methodName));
        Log.d("zkq", "2222222222222222");
    }
}

6、在mainActivity.java中的任意方法就可以使用了,我这里是一个点击事件

    @BehaviorTrance("点击方法")
    public void onAspectj(View view) {
        Log.d("zkq","111111");
    }

总结

在BehaviorTraceAspect中如果我们用到的是Around就需要使用ProceedingJoinPoint并且抛出Throwable,并且在目标执行中执行的先后顺序是由Object result = joinPoint.proceed()来决定的

    @Around("methodAnnottatedWithBehaviorTrace()")
    private Object methodBehaviorTrace(ProceedingJoinPoint joinPoint) throws Throwable{
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        String className = methodSignature.getDeclaringTypeName();
        String methodName = methodSignature.getName();
        String value = methodSignature.getMethod().getAnnotation(BehaviorTrance.class).value();
        Log.d("zkq", String.format("%s功能:%s类的%s方法执行了",value, className, methodName));
        Object result = joinPoint.proceed();
        return result;
    }

demo下载地址: demo下载

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值