AOP基本思想
AOP是什么?
AOP意思为面向切面的编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术
为什么使用AOP?
利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率
原理图 image
场景举例
在程序开发中,假如现在有一个需求,就是在程序各处验证用户权限,如果还是oop的思想,那么在各处就要做一次判断。但是如果运用aop的思想,我们可以通过注解收集问题,然后提供一个切面统一处理。
Android中AOP基本使用
基本Api
- @Aspect:声明切面,标记类,使用下面注解之前一定要在类使用@Aspec
- execution(@注解类全路径 * *(..))
- @Pointcut("execution(@注解类全路径 * *(..))")
- @Before:切点之前执行
- @Afte:切点之后执行
- @AfterReturning:返回通知,切点方法返回结果之后执行
- @AfterThrowing:异常通知,切点抛出异常时执行
- @Around 切点前后执行
配置
dependencies {
classpath 'com.android.tools.build:gradle:3.5.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
//aspectj框架
classpath 'org.aspectj:aspectjtools:1.8.9'
classpath 'org.aspectj:aspectjweaver:1.8.9'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
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 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 {
//使用aspectj框架
implementation 'org.aspectj:aspectjrt:1.8.9'
}
简单使用
- 注解类 LogTrace
- 切面类 MyAopTest
- 切入点类 AopTest1Activity
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface LogTrace {
String value() default "";
}
@Aspect
public class MyAopTest {
/*
* 切入点
* @com.cbb.seeandroid.aop.LogTrace 切入的注解类全路径
* * *(..)) 所有类 所有方法(不限参数)
* */
@Pointcut("execution(@com.cbb.seeandroid.aop.LogTrace * *(..))")
public void pointCut(){
}
@Around("pointCut()")
public Object logs(ProceedingJoinPoint joinPoint) throws Throwable {
Signature signature = joinPoint.getSignature();
// 切入点全类名
String declaringTypeName = signature.getDeclaringTypeName();
// 切入点方法名
String name = signature.getName();
Log.e("----------->",declaringTypeName+"中的"+name+"方法");
Log.e("----------->","方法调用前");
Object proceed = joinPoint.proceed();
Log.e("----------->","方法调用后");
return proceed;
}
}
public class AopTest1Activity extends AppCompatActivity {
public static final String TAG = AopTest1Activity.class.getSimpleName();
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_aop_test);
}
public void start(View view) {
aopTest();
}
@LogTrace
public void aopTest(){
Log.e(TAG,"-->aopTest()");
}
}
运行结果为
2020-05-25 10:55:14.905 11284-11284/com.cbb.seeandroid E/----------->: com.cbb.seeandroid.aop.AopTest1Activity中的aopTest方法
2020-05-25 10:55:14.905 11284-11284/com.cbb.seeandroid E/----------->: 方法调用前
2020-05-25 10:55:14.905 11284-11284/com.cbb.seeandroid E/AopTest1Activity: -->aopTest()
2020-05-25 10:55:14.905 11284-11284/com.cbb.seeandroid E/----------->: 方法调用后
网友评论