美文网首页
AOP切面编程

AOP切面编程

作者: 爬行的蚂蚁2725 | 来源:发表于2018-12-24 17:32 被阅读0次

aop是一套所有架构师(不限语言)都必需掌握的技术,主要应用于全局业务,如性能监测、权限验证、释放资源、用户行为统计等。
使用工具:Android中可以使用aspectj工具。
原理:可以用于在android 打包,class转换成dex 过程中,加入开发者自定义的处理逻辑.
核心技术:动态代理,遵循java编译原则,编译修改后的class文件。
具体使用步骤:
1.在将aspectjrt.jar包添加到libs目录并引入。
2.在app的build.gradle中加入如下配置


buildscript {
  repositories {
    mavenCentral()
  }
dependencies {
    classpath'org.aspectj:aspectjtools:1.8.8'
        classpath'org.aspectj:aspectjweaver:1.8.8'
    }
}

....
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.8",
                         "-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;
            }
        }
    }
}

3.创建注解,如性能检测注解

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

4.在需要检测的方法上添加改注解

@BehaviorTrace("摇一摇")
public void shakeClick(View view) {
      SystemClock.sleep(new Random().nextInt(2000));
}

5.创建一个切面类,添加@Aspect注解

@Aspect
public class BehaviorTraceAspect {
    //定义切面的规则
    //1.就在原来应用中哪些注释的地方放到当前切面进行处理
    //execution(注释名   注释用的地方)
//@后面为自定义注解的全类名
// * *(..) 表示任何类 任何方法(任何参数)
    @Pointcut("execution(@com.example.testdemo.annotation.BehaviorTrace * *(..))")
    public void methodAnnotatedWithBehaviorTrace(){}

    //2.对进入切面的内容如何处理
    //advice
    //@Before()  在切入点之前运行
    //@After()   在切入点之后运行
    //@Around()  在切入点前后都运行
    @Around("methodAnnotatedWithBehaviorTrace()")
    public Object weaveJoinPoint(ProceedingJoinPoint joinPoint) throws Throwable{
        MethodSignature methodSignature=(MethodSignature)joinPoint.getSignature();
        String className=methodSignature.getDeclaringType().getSimpleName();
        String methodName=methodSignature.getName();
        String funName=methodSignature.getMethod().getAnnotation(BehaviorTrace.class).value();

        //统计时间
        long begin=System.currentTimeMillis();
        Object result=joinPoint.proceed();
        long duration=System.currentTimeMillis()-begin;
        Log.d("yxg",String.format("功能:%s,%s类的%s方法执行了,用时%d ms",funName,className,methodName,duration));
        return result;
    }
}

相关文章

网友评论

      本文标题:AOP切面编程

      本文链接:https://www.haomeiwen.com/subject/rcgzkqtx.html