
前言
- 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...