SpringBoot电脑商城项目--AOP统计业务方法耗时

AOP统计业务方法耗时

        AOP(Aspect-Oriented Programming,面向切面编程)是一种编程范式,旨在提高代码的模块化,通过分离**横切关注点**(cross-cutting concerns)来增强代码的可维护性和复用性。

1. 概念

1.1  核心概念

切面(Aspect)

           一个模块化的单元,封装了与业务逻辑无关的公共行为(如日志、权限控制)。例如,`LoggingAspect` 是一个典型的切面类。

连接点(Join Point)

           程序执行过程中的某个点,如方法调用或异常抛出。AOP可以在这些点插入自定义逻辑。

切点(Pointcut)

           定义哪些连接点会被切面拦截。例如,`execution(* com.example.service.*.*(..))` 表示拦截 `com.example.service` 包下所有方法的执行。

通知(Advice)

   切面在特定连接点上执行的动作。常见类型包括:

  • @Before:在目标方法执行前运行。
  • @After:在目标方法执行后运行(无论是否成功)。
  • @AfterReturning:在目标方法成功返回后运行。
  • @AfterThrowing:在目标方法抛出异常后运行。
  • @Around:环绕目标方法,可控制方法的执行(如添加缓存或事务管理)。

织入(Weaving)
   将切面逻辑合并到目标对象的过程。织入可以在编译时、类加载时或运行时完成。

1.2  优点

  • 解耦:将公共逻辑从业务代码中分离,减少重复代码。
  • 增强可维护性:修改切面逻辑无需改动业务代码。
  • 提升可读性:业务代码更专注于核心逻辑,避免杂糅其他职责。

2. 在SpringBoot电脑商城项目使用AOP

2.1 导入依赖


        
            org.aspectj
            aspectjweaver
        
        
            org.aspectj
            aspectjtools
        

2.2 定义一个切面类

package com.cy.store.aop;

import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

// 被spring容器管理
@Component
// 告诉spring当前类是一个切面类
@Aspect
public class TimerAspect {
}

2.3 在切面类中定义切面方法

        使用环绕通知的方式来进行编写

          ProceedingJoinPoint 是 Spring AOP 和 AspectJ 中的一个接口,用于表示一个可执行的连接点(Join Point)。在切面中使用 @Around 环绕通知时,会传入一个 ProceedingJoinPoint 类型的参数,它允许你控制目标方法的执行流程。

package com.cy.store.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

// 被spring容器管理
@Component
// 告诉spring当前类是一个切面类
@Aspect
public class TimerAspect {
    /**
     * 定义环绕通知,用于统计目标方法的执行时间
     * 切入点为 com.cy.store.service.impl 包下的所有方法
     * @param joinPoint 连接点对象,包含目标方法的信息
     * @return Object 目标方法返回值
     * @throws Throwable 异常信息
     */
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        // 记录方法开始执行前的时间戳
        long start = System.currentTimeMillis();
        
        // 执行目标方法,并获取返回值
        Object ret = joinPoint.proceed();
        
        // 记录方法执行结束的时间戳
        long end = System.currentTimeMillis();
        
        // 打印目标方法执行耗时
        System.out.println("耗时:" + (end - start));
        
        return ret;
    }
}

2.4 指定连接点

        将当前环绕通知映射到某个页面上(指定连接点)


   @Around("execution(* com.cy.store.service.impl.*.*(..))")

完整代码

package com.cy.store.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

// 被spring容器管理
@Component
// 告诉spring当前类是一个切面类
@Aspect
public class TimerAspect {
    /**
     * 定义环绕通知,用于统计目标方法的执行时间
     * 切入点为 com.cy.store.service.impl 包下的所有方法
     * @param joinPoint 连接点对象,包含目标方法的信息
     * @return Object 目标方法返回值
     * @throws Throwable 异常信息
     */
    @Around("execution(* com.cy.store.service.impl.*.*(..))")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        // 记录方法开始执行前的时间戳
        long start = System.currentTimeMillis();
        
        // 执行目标方法,并获取返回值
        Object ret = joinPoint.proceed();
        
        // 记录方法执行结束的时间戳
        long end = System.currentTimeMillis();
        
        // 打印目标方法执行耗时
        System.out.println("耗时:" + (end - start));
        
        return ret;
    }
}

2.5 启动项目,随机访问任意功能模块

你可能感兴趣的:(spring,boot,java,后端,AOP,切面)