前言
- AspectJ 是一个流行的 Java AOP(aspect-oriented programming)编程扩展框架,基于注解处理器 & 运行时注解反射的原理。
- 在这篇文章里,我将带你梳理 AspectJ 的使用攻略 & 原理,追求简单易懂又不失深度,如果能帮上忙,请务必点赞加关注!
系列文章
延伸文章
- 关于反射,请阅读:《Java | 反射:在运行时访问类型信息(含 Kotlin)》
- 关于注解,请阅读:《Java | 这是一篇全面的注解使用攻略(含 Kotlin)》
- 关于注解处理器(APT),请阅读:《Java | 注解处理器(APT)原理解析 & 实践》
目录
Editing...
操作Java代码
1、面向切面编程 简介
定义
一种编程思想作用
通过分离横切关注点(cross-cutting concerns)
来维持程序模块化为什么要使用
AOP
?
面向切面编程 示意图
- 总结
AOP
是OOP
的补充和完善,AOP
将特殊步骤从核心业务模块单元单独提炼出来,命名为横切步骤
,横切步骤构成切面(Aspect)
;- 将特殊功能统一织入的实现方式有:
编译期织入
、类加载期织入
、运行期动态代理织入
。
2、AspectJ 框架简介
定义
一个Java面向对象切面编程
扩展框架作用
处理字节码
文件,在编译期
将横切关注点织入核心业务逻辑为什么使用
AspectJ
框架`?
AspectJ 示意图
- 总结
3. 相关概念
- 关于
AspectJ
的相关概念如下,在下面的分享中,我将直接使用英文名:
Editing...
4. 示例 —— 限制按钮快速点击
- 我们通过一个集成
AspectJX
的示例带大家理解AspectJ
的相关概念; - 在这里,我们构建了
FastClickCheckerAspect切面
,将限制快速点击的逻辑织入View#OnClickListener
的实现逻辑。请务必阅读文章:《Android | 使用 AspectJ 限制按钮快速点击》,查看完整示例。
步骤1:添加依赖
- 需依赖
沪江 Gradle插件
与AspectJ框架
,具体步骤见上述文章;
步骤2:判断View快速点击的工具类
- 实现一个根据
点击间隔阈值
判断是否为快速点击的工具类,具体描述见上述文章;
public class FastClickCheckUtil {
/**
* 判断是否属于快速点击
*
* @param view 点击的View
* @param interval 快速点击的阈值
* @return true:快速点击
*/
public static boolean isFastClick(@NonNull View view, int interval) {
// 实现省略,详见上述文章
}
}
步骤3:定义Aspect
切面
使用@Aspect注解
描述一个切面
,使用该注解修饰的类会被AspectJ编译器
识别为切面类:
@Aspect
public class FastClickCheckerAspect {
// 随后填充
}
步骤4:定义PointCut
切入点
使用@Pointcut注解
描述一个切入点
,编译期AspectJ编译器
将搜索所有匹配的JoinPoint
,执行织入:
@Aspect
public class FastClickCheckerAspect {
// 定义一个切入点:View.OnClickListener#onClick()方法
@Pointcut("execution(void android.view.View.OnClickListener.onClick(..))")
public void methodViewOnClick() {
}
// 随后填充 Advice
}
步骤5:定义Advice
增强
增强的方式有很多种,在这里我们使用@Around注解
定义环绕增强
,它将包装PointCut
,在PointCut
前后增加横切逻辑,具体如下:
@Aspect
public class FastClickCheckerAspect {
// 定义切入点:View.OnClickListener#onClick()方法
@Pointcut("execution(void android.view.View.OnClickListener.onClick(..))")
public void methodViewOnClick() {
}
// 定义环绕增强,包装methodViewOnClick()切入点
@Around("methodViewOnClick()")
public void aroundViewOnClick(ProceedingJoinPoint joinPoint) throws Throwable {
// 取出目标对象
View target = (View) joinPoint.getArgs()[0];
// 根据点击间隔是否超过2000,判断是否为快速点击
if (!FastClickCheckUtil.isFastClick(target, 2000)) {
joinPoint.proceed();
}
}
}
步骤6:实现View.OnClickListener
在这一步我们为View设置OnClickListener,可以看到我们并没有添加限制快速点击的相关代码,增强的逻辑对原有逻辑没有侵入,具体代码如下:
// 源码:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.text).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.i("AspectJ","click");
}
});
}
}
小结
到这里,我们就展示完使用AspectJ
限制快速点击的示例了,请务必查看文章:《Android | 使用 AspectJ 限制按钮快速点击》 查看完整示例。接下来我们将具体描述AspectJ
的每个使用步骤。
5. JoinPoint 连接点
Editing...
6. PointCut 表达式
Editing...