AOP笔记

AOP技术用于解决横切关注点问题,如多个方法需执行相同任务。在Spring中,@Aspect注解标识切面类,@Around注解用于环绕通知,可以在方法执行前后添加自定义逻辑。文章举例展示了如何使用@Around注解实现方法执行时间的计时功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

AOP:面向切面编程

注意:AOP并不是Spring原创的技术,也不是Spring独家技术,而是源自AspectJ,只是Spring很好的支持了AOP。

AOP技术只要解决了“横切关注”的相关问题,也就是“若干个不同的方法都需要执行相同的任务”的问题!

@Slf4j
@Aspect // 标记当前类是一个切面类
@Component // 标记当前类是一个组件类,则Spring会进行处理
public class TimerAspect {

    // 连接点(JoinPoint):程序执行过程中的某个节点,可能是某个方法的调整,或是某个方法抛出了异常
    // 切入点(PointCut):匹配连接点的表达式
    // -------------------------------------------------------------------
    // 通知(Advice)注解:
    // @Around:环绕,可以包裹连接点的执行,所以,你可以在执行连接点之前和之后编写你所需的代码
    // @Before:在执行连接点之前
    // @After:在执行连接点之后
    // @AfterThrowing:在抛出异常之后
    // @AfterReturning:在成功返回之后
    // -------------------------------------------------------------------
    // 各通知的执行点大致是以下这样:
    // @Around开始
    // try {
    //      @Before
    //      执行连接点
    //      @AfterReturning
    // } catch (Throwable e) {
    //      @AfterThrowing
    // } finally {
    //      @After
    // }
    // @Around结束
    // -------------------------------------------------------------------
    // 切入点表达式:匹配某些方法
    // 可以使用通配符:
    // - 星号(*):任意有且仅有1次匹配
    // - 2个连接的小数点(..):任意n次匹配,仅能用于包名和参数列表
    //                 ↓ 返回值类型
    //                   ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ 包名
    //                                                  ↓ 类名
    //                                                    ↓ 方法名
    //                                                      ↓↓ 参数列表
    // 在切入点表达式中,在返回值类型声明的左侧,还可以指定修饰符,修饰符是可选的
    // 如果没有显式的指定修饰符,则无论什么修饰符都可以匹配
    // 其实,其它部分也是如此,例如,如果没有指定包名,则无视匹配的类在哪个包下
    // 注意:注解是典型的修饰符
    // 注意:无论是注解,还是返回值、参数,只要不是基本数据类型、java.lang包下的类型,都必须使用全限定名
    @Around("execution(* cn.*.tea.admin.server..service.*.*(..))")
    //     ↓↓↓↓↓↓ 使用@Around时必须声明为ProceedingJoinPoint对象调用proceed()返回的结果
    //            ↓↓↓↓↓ 自定义的方法名
    //                  ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ 使用@Around时必须是ProceedingJoinPoint类型
    //                                           ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ 必须抛出
    public Object timer(ProceedingJoinPoint pjp) throws Throwable {
        log.trace("TimerAspect.timer()开始执行");
        // 获取连接点信息
        String targetClassName = pjp.getTarget().getClass().getName(); // 类型名
        String signatureName = pjp.getSignature().getName(); // 方法名
        Object[] args = pjp.getArgs(); // 参数列表
        System.out.println("连接点(方法)所属的类的名称:" + targetClassName);
        System.out.println("连接点(方法)的名称:" + signatureName);
        System.out.println("连接点(方法)的参数列表:" + Arrays.toString(args));
        // 获取起始时间
        long start = System.currentTimeMillis();
        // 调用ProceedingJoinPoint参数对象的proceed()方法,表示执行连接点,即调用了匹配到的方法
        // 注意-1:调用proceed()方法的异常,必须抛出,不可以简单的try...catch(除非在catch中再抛出异常)
        // 注意-2:调用proceed()方法时返回的结果,表示对应的Service方法的返回值,必须作为当前切面方法的返回值
        Object proceedResult = pjp.proceed();
        // 获取结束时间
        long end = System.currentTimeMillis();
        // 输出
        System.out.println("执行耗时:" + (end - start));
        log.trace("TimerAspect.timer()执行结束,即将返回");
        return proceedResult;
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值