JAVA:面向切面编程AOP

一、定义

        把某一些功能提取出来与某一对象进行隔离,提取之后可以对某哥单方面的功能进行修改和扩展

        也就是把众多方法中的的所有公共代码抽取出来,放到某个地方集中管理

        对业务逻辑的各个部分进行了隔离,从而降低业务逻辑各部分之间的耦合,提高程序的可重用性,提高开发效率。

二、面向切面思想体现

  1. 动态代理(AOP),比如说用动态代理去判断MVP中的model是否为空
  2. 在application中对activity注册生命周期的监听
  3. 基于第三方的编译工具:APT、AspectJ、Javassist等

三、与OOP(面向对象编程)的区别

        OOP是把问题划分到单个模块

        AOP是把涉及到众多模块的某一类问题进行统一管理,

四、AOP使用场景

  • 参数校验和判空
  • 权限检测、网络检测等 
  • 埋点
  • 安全控制
  • 日志记录
  • 性能统计
  • 异常处理
    替代防御性的 try-Catch

  • 缓存
    缓存某方法的返回值,下次执行该方法时,直接从缓存里获取

  • 热修复

五、AspectJ使用方法

@Aspect:声明切面,标记类
@Pointcut(切点表达式):定义切点,标记方法
@Before(切点表达式):前置通知,切点之前执行
@Around(切点表达式):环绕通知,切点前后执行
@After(切点表达式):后置通知,切点之后执行
@AfterReturning(切点表达式):返回通知,切点方法返回结果之后执行
@AfterThrowing(切点表达式):异常通知,切点抛出异常时执行
 
注:如果没有添加@Aspect,那么后面的注解一律不起作用

1.在项目下gradle添加依赖

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

2.在使用的模块gradle添加

import org.aspectj.bridge.IMessage
import org.aspectj.bridge.MessageHandler
import org.aspectj.tools.ajc.Mainandroid {……
}final def log = project.logger
final def variants = project.android.applicationVariantsvariants.all { variant ->if (!variant.buildType.isDebuggable()) {log.debug("Skipping non-debuggable build type '${variant.buildType.name}'.")return;}JavaCompile javaCompile = variant.javaCompilejavaCompile.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.thrownbreak;case IMessage.WARNING:log.warn message.message, message.thrownbreak;case IMessage.INFO:log.info message.message, message.thrownbreak;case IMessage.DEBUG:log.debug message.message, message.thrownbreak;}}}
}dependencies {……implementation 'org.aspectj:aspectjrt:1.8.9'
}

3.创建注解,标记切点

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)ButterKnife   SOURCE 代表资源
public @interface CheckNet {}

4.处理切点

@Aspect //声明切面
public class SectionAspect {/*** 找到处理的切点* * *(..)  可以处理所有的方法*/@Pointcut("execution(@com.darren.architect_day02.CheckNet * *(..))")public void checkNetBehavior() {}/*** 处理切面*/@Around("checkNetBehavior()")public Object checkNet(ProceedingJoinPoint joinPoint) throws Throwable {MethodSignature signature = (MethodSignature) joinPoint.getSignature();CheckNet checkNet = signature.getMethod().getAnnotation(CheckNet.class);if (checkNet != null) {Object object = joinPoint.getThis();Context context = getContext(object);if (context != null) {if (!isNetworkAvailable(context)) {//处理公共事件Toast.makeText(context,"请检查您的网络",Toast.LENGTH_LONG).show();return null;}}}return joinPoint.proceed();}
}

六、AspectJ原理

        运行时,使用了aspectJ第三方编译器,aspectJ去修改class文件,不影响性能


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部