一、定义
把某一些功能提取出来与某一对象进行隔离,提取之后可以对某哥单方面的功能进行修改和扩展
也就是把众多方法中的的所有公共代码抽取出来,放到某个地方集中管理
对业务逻辑的各个部分进行了隔离,从而降低业务逻辑各部分之间的耦合,提高程序的可重用性,提高开发效率。
二、面向切面思想体现
- 动态代理(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.Main
android {
……
}
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;
}
}
}
}
dependencies {
……
implementation 'org.aspectj:aspectjrt:1.8.9'
}
3.创建注解,标记切点
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)ButterKnife SOURCE 代表资源
public @interface CheckNet {
}
4.处理切点文章来源:https://www.toymoban.com/news/detail-732735.html
@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文件,不影响性能文章来源地址https://www.toymoban.com/news/detail-732735.html
到了这里,关于JAVA:面向切面编程AOP的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!