A weird runtime AOP framework. 一个奇怪的运行时AOP框架。
用一个接口包装真正的方法的逻辑,再通过创建匿名类获取当前执行的方法Method
并代理执行前面包装的逻辑。在中间通过自定义的切面控制方法该如何调用。缺点是对每一个使用KAop的方法创建两个类,牺牲空间和性能换取AOP。
1.[DEMO]权限请求KXXPermissions,基于XXPermissions
1.继承Aspect
,如TimeCostAspect
,实现了对方法执行时间的计算。
public class TimeCostAspect extends Aspect {
private long time = 0;
@Override
public void before(@NonNull AbsJoinPoint point) {
time = System.currentTimeMillis();
}
@Override
public void after(@NonNull AbsJoinPoint point) {
Log.d("TimeCost", (System.currentTimeMillis() - time) + "ms");
}
}
对于Kotlin调用: 定义一个注解,使用@AspectAnnotation
注解该注解,并且指定plugin
使用TimeCostAspect
。
其中int order() default 0;
代表切面的执行顺序,越小越先执行。order
为一个约定的名称,可以不定义该参数。默认为Int.MAX_VALUE
。
对于Java调用: 必须要标记注解@Retention(RetentionPolicy.RUNTIME)
,kotlin默认是RUNTIME。
@AspectAnnotation(plugin = TimeCostAspect.class)
@Retention(RetentionPolicy.RUNTIME)
public @interface TimeCost {
int order() default 0;
}
Kotlin
在需要切面的类初始化,在需要切面的函数标记定义的注解,函数用pointcut{...}
包裹一层,其中pointcut
是初始化返回的对象,这里override了他的invoke操作。
class KtClassCase {
private val pointcut = KAop(this)
@NeedToken
fun test():String = pointcut{
return@pointcut "操作成功"
}
}
object KtObjectCase {
private val pointcut = KAop(this)
@NeedToken
fun testStatic():String = pointcut{
return@pointcut "操作成功"
}
@NeedToken
@JvmStatic
fun testJvmStatic():String = pointcut{
return@pointcut "操作成功"
}
}
Java
在Java中使用略显繁琐,这里只是做了个对Java的兼容,建议使用Kotlin。
注意,创建MethodGetter对象时后面的{}
正确:new MethodGetter<...>(..., ...){}.proxy();
错误:new MethodGetter<...>(..., ...).proxy();
public class JavaCase {
private final Pointcut pointcut = KAop.inject(this);
@NeedToken
public String test(){
return new MethodGetter<String>(pointcut, scope-> "操作成功"){}.proxy();
}
private static final Pointcut pointcutStatic = KAop.inject(JavaCase.class);
@NeedToken
public static String testStatic(){
return new MethodGetter<String>(pointcutStatic, scope-> "操作成功"){}.proxy();
}
}