Android | 一文带你全面了解 AspectJ 框架

前言

  • AspectJ是一个流行的Java AOP(aspect-oriented programming)编程扩展框架;
  • 今天,我将整理AspectJ详细的使用教程,希望你们喜欢。

目录

Editing...


1、面向切面编程 简介

  • 定义
    一种编程思想

  • 作用
    通过分离横切关注点(cross-cutting concerns)来维持程序模块化

  • 为什么要使用AOP?

面向切面编程 示意图
  • 总结
    • AOPOOP的补充和完善,AOP将特殊步骤从核心业务模块单元单独提炼出来,命名为横切步骤,横切步骤构成切面(Aspect)
    • 将特殊功能统一织入的实现方式有:编译期织入类加载期织入运行期动态代理织入

2、AspectJ 框架简介

  • 定义
    一个Java面向对象切面编程扩展框架

  • 作用
    处理字节码文件,在编译期将横切关注点织入核心业务逻辑

  • 为什么使用AspectJ框架`?

AspectJ 示意图
  • 总结
    • AspectJ处理字节码文件,在编译期匹配PointCut,重构JoinPoint,实现横切逻辑Weaving核心业务逻辑;
    • Android中使用AspectJ推荐集成沪江的 AspectJX 工具和Jake Wharton的 Hugo工具。

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