好家伙,核心代码不到200行写了一个aop框架

一.AOP框架实战:轻松实现面向切面编程

1. 简介

AOP(Aspect-Oriented Programming,面向切面编程)是一种编程范式,它允许程序员以模块化的方式添加功能到应用程序。AOP框架通过在程序执行的特定时间点插入代码(称之为切面)来实现这一点。

2. AOP框架的核心概念

  • 切点(Pointcut): 定义了通知应该应用于哪些方法。
  • 通知/切面(Advice): 在连接点执行的代码。
  • 连接点(JoinPoint): 目标方法的执行点。

3. AOP框架的应用场景

  • 日志记录
  • 性能监控
  • 事务管理
  • 安全检查

4. AOP框架一般这么用

  • 定义切点
  • 定义通知/切面
  • 将切点和通知应用到目标方法
  • 创建代理对象

5. AOP框架的优点

  • 模块化:AOP框架可以将应用程序的功能模块化,使应用程序更易于维护和扩展。
  • 可重用性:AOP框架可以将通知代码重用在多个应用程序中。
  • 降低耦合度:AOP框架可以降低应用程序组件之间的耦合度。

6. AOP框架的缺点

  • 性能开销:AOP框架可能会引入一定的性能开销。
  • 代码复杂度:AOP框架可能会使应用程序的代码变得更加复杂。

7. AOP框架的选型

目前有许多流行的AOP框架可供选择,包括:

  • AspectJ
  • Spring AOP
  • CGLib

在选择AOP框架时,需要考虑以下因素:

  • 应用程序的规模和复杂度
  • 应用程序的性能要求
  • 应用程序的开发语言和平台

二.手把手教你用 Java 编写一个简单的 AOP 框架

1. 手撸 AOP 框架介绍

我最近编写了一个简单的 AOP 框架,它可以帮助程序员轻松地实现面向切面编程。我的 AOP 框架具有以下特点:

  • 简单易用: 只需几行代码,即可将通知应用到目标方法。
  • 功能强大: 支持多种类型的通知,包括前置通知、后置通知、返回通知、异常通知和环绕通知。
  • 可扩展: 可以通过编写自定义的通知来扩展框架的功能。

2.核心代码

2.1切点

/**
 * 切点类
 * 1.使用切点表达式来指定通知应该应用于哪些方法
 * 2.使用 Pointcut 实例来检查方法是否匹配切点表达式
 * 3.使用 Pointcut 实例来组合更复杂的切点表达式
 * Pointcut 的作用和职责:
 * 指定通知应该应用于哪些方法: Pointcut 用于指定通知应该应用于哪些方法。我们可以使用切点表达式来定义 Pointcut。切点表达式是一种特殊的字符串,它可以匹配方法签名。
 * 例如,以下切点表达式匹配所有以 save 开头的方法:execution(public void aa.bb.cc.Test.save*(..))
 */
public interface Pointcut {
    boolean matches(Object object);
    /**
     * 表达式
     */
    String getPointcutExpression();

    /**
     * tag对象
     */
    void setTag(Object tag);
}

2.2切面

/**
 * 切面行接受通知后可执行相应逻辑
 */
public interface Advice {
    //执行
    void execute(JoinPoint joinPoint) throws Throwable;
    //通知配型
    Configurator config();
}

2.3连接点

/**
 * 连接点类
 * 1.向通知传递有关连接点的信息
 * 2.在通知中获取有关连接点的信息
 * 作用:通知与连接点进行交互,并传递和获取有关连接点的信息,对它进行扩展可获得以下信息。
 * 例如,方法调用、字段访问、异常抛出等。JoinPoint 可以传递的信息包括目标对象、方法名、参数、返回值、异常对象等。
 * 例如,我们可以使用 JoinPoint 来获取目标对象、方法名、参数、返回值、异常对象等信息。
 * 例如,我们可以使用 JoinPoint 来修改方法的参数、返回值或抛出异常
 */
public interface JoinPoint {

    Object getTarget();

    String getMethodName();

    Object[] getArgs();
}

2.4多通知

/**
 * 切点类型通知类,定义通知的类型
 *      不同的通知有一定的应用场景。
 *      *环绕通知:
 *      *  记录日志,性能监控
 *      *  事务管理,在目标方法执行之前和之后进行事务管理,可以确保目标方法在事务中执行。
 *      *
 *      * 异常通知:
 *      *   记录日志,在目标方法执行之后且抛出异常时记录日志,可以帮助我们了解目标方法的执行情况。
 *      *   发送邮件,在目标方法执行之后且抛出异常时发送邮件,可以通知相关人员目标方法执行失败。
 *      *   回滚事务,在目标方法执行之后且抛出异常时回滚事务,可以防止数据不一致。
 *      *
 *      * 最终通知:
 *      * 资源释放,不管目标方法执行是否成功,最终会释放一些资源。
 *      *
 *      * 前置通知:
 *      *   检查权限,在目标方法执行之前检查权限,可以防止未授权用户访问受保护的资源。
 *      *   初始化资源,在目标方法执行之前初始化资源,可以确保目标方法能够正常执行。
 *      *
 *      * 后置通知:
 *      *   清理资源,在目标方法执行之后清理资源,可以防止资源泄漏。
 *      *   更新缓存,在目标方法执行之后更新缓存,可以提高应用程序的性能。
 *
 */
public enum AdviceType {

    BEFORE("before"),   // 在方法调用之前执行通知
    AFTER("after"),     // 在方法调用之后执行通知
    AROUND("around"),   // 在方法调用前后执行通知
    AFTER_THROWING("afterThrowing"), // 在方法抛出异常之后执行通知
    AFTER_FINALLY("afterFinally");   // 目标方法无论是否执行成功后执行通知

    public enum AROUND_S{
        A_BEFORE,A_AFTER
    }

    private final String name;

    AdviceType(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    private AROUND_S aroundS;

    public void setAroundS(AROUND_S aroundS) {