Aop

9 阅读1分钟

面向切面编程

应用场景

image.png

通过动态代理实现

~其他应用场景

image.png

3.编程步骤

image.png

1


<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjrt</artifactId>
    <version>1.9.19</version>
</dependency>

image.png

image.png

统计某些目标方法的运行时间

1.通过around环绕拦截目标方法

2.pjp代表了当前被拦截的对象

3.核心逻辑 放行被拦截的方法 Object result接受方法执行完的结果

4.最后不要忘记返回result

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

/**
 * 统计数据库查询(select开头的方法)耗时的 AOP 切面
 */
@Component // 1. 将这个切面类交给 Spring 容器管理
@Aspect    // 2. 标识这是一个 AOP 切面类
public class SelectMethodTimeAspect {

    /**
     * @Around 环绕通知
     * execution(...) 表达式用于匹配目标方法。
     * 这里的表达式含义是:拦截 com.yourproject 包及其子包下,所有类中以 "select" 开头的任意方法。
     */
    @Around("execution(* com.yourproject..*.select*(..))")
    public Object measureSelectTime(ProceedingJoinPoint pjp) throws Throwable {
        
        // 1. 记录方法执行前的毫秒级时间戳 (如果是极短方法可用 System.nanoTime())
        long start = System.currentTimeMillis();
        
        // 2. 放行,执行目标业务方法(即真正的 select 查询)
        Object result = pjp.proceed();
        
        // 3. 记录方法执行后的时间戳
        long end = System.currentTimeMillis();
        
        // 4. 计算耗时
        long timeTaken = end - start;
        
        // 获取目标方法签名,方便在日志中知道是哪个方法
        String methodName = pjp.getSignature().toShortString();
        
        // 打印耗时(实际开发中建议替换为 log.info 或 log.warn)
        System.out.println("【性能监控】查询方法 " + methodName + " 运行耗时: " + timeTaken + " ms");
        
        // 5. 返回目标方法的执行结果
        return result;
    }
}