JAVA:面向切面编程AOP
一、定义
把某一些功能提取出来与某一对象进行隔离,提取之后可以对某哥单方面的功能进行修改和扩展
也就是把众多方法中的的所有公共代码抽取出来,放到某个地方集中管理
对业务逻辑的各个部分进行了隔离,从而降低业务逻辑各部分之间的耦合,提高程序的可重用性,提高开发效率。
二、面向切面思想体现
- 动态代理(AOP),比如说用动态代理去判断MVP中的model是否为空
- 在application中对activity注册生命周期的监听
- 基于第三方的编译工具: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文件,不影响性能
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
