当前位置: 首页 > news >正文

Spring AOP中为所有类型通知传递参数的完整示例,包含详细注释和参数传递方式

以下是Spring AOP中为所有类型通知传递参数的完整示例,包含详细注释和参数传递方式:

// 1. 目标类(被增强的类)
package com.example;

public class TargetService {
    public void doTask(String param) {
        System.out.println("执行业务逻辑,参数:" + param);
    }

    public void doTaskWithoutParam() {
        System.out.println("执行无参业务逻辑");
    }

    public void doTaskWithError() throws Exception {
        System.out.println("执行会抛异常的逻辑");
        throw new RuntimeException("模拟异常");
    }
}
// 2. 切面类(包含所有通知类型)
package com.example;

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

@Aspect
@Component
public class ParameterAspect {

    // 前置通知:通过JoinPoint获取参数
    @Before("execution(* com.example.TargetService.*(..))")
    public void beforeAdvice(JoinPoint joinPoint) {
        System.out.println("前置通知:方法开始");
        Object[] args = joinPoint.getArgs();
        for (Object arg : args) {
            System.out.println("参数值:" + arg);
        }
    }

    // 后置通知:返回值和参数
    @AfterReturning(
        pointcut = "execution(* com.example.TargetService.*(..))",
        returning = "result"
    )
    public void afterReturningAdvice(JoinPoint joinPoint, Object result) {
        System.out.println("后置通知:方法正常返回");
        System.out.println("返回值:" + result);
        System.out.println("参数列表:" + joinPoint.getArgs());
    }

    // 异常通知:捕获异常和参数
    @AfterThrowing(
        pointcut = "execution(* com.example.TargetService.*(..))",
        throwing = "ex"
    )
    public void afterThrowingAdvice(JoinPoint joinPoint, Throwable ex) {
        System.out.println("异常通知:方法抛出异常");
        System.out.println("异常信息:" + ex.getMessage());
        System.out.println("异常发生时的参数:" + joinPoint.getArgs());
    }

    // 环绕通知:直接操作ProceedingJoinPoint
    @Around("execution(* com.example.TargetService.*(..))")
    public Object aroundAdvice(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("环绕通知:方法执行前");
        System.out.println("方法参数:" + pjp.getArgs());
        
        try {
            Object result = pjp.proceed();
            System.out.println("环绕通知:方法执行后");
            return result;
        } catch (Throwable ex) {
            System.out.println("环绕通知:捕获异常");
            throw ex;
        }
    }

    // 引介通知:不直接传递参数(示例展示引入接口)
    @DeclareParents(
        value = "com.example.TargetService+",
        defaultImpl = AuditLogImpl.class
    )
    private AuditLog auditLog;

    private static class AuditLogImpl implements AuditLog {
        @Override
        public void log() {
            System.out.println("引介通知:记录审计日志");
        }
    }
}
// 3. Spring配置类
package com.example;

import org.springframework.context.annotation.*;

@Configuration
@ComponentScan("com.example")
@EnableAspectJAutoProxy
public class AppConfig {
    @Bean
    public TargetService targetService() {
        return new TargetService();
    }
}
// 4. 测试类
public class Main {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = 
            new AnnotationConfigApplicationContext(AppConfig.class);
        
        TargetService service = context.getBean(TargetService.class);
        
        // 测试正常流程
        service.doTask("参数1");
        
        // 测试无参方法
        service.doTaskWithoutParam();
        
        // 测试异常流程
        try {
            service.doTaskWithError();
        } catch (Exception e) {
            System.out.println("捕获到异常:" + e.getMessage());
        }
        
        // 测试引介接口
        AuditLog audit = (AuditLog) service;
        audit.log();
    }
}

关键点总结表格

通知类型参数传递方式示例代码片段参数来源说明
前置通知JoinPoint.getArgs()Object[] args = joinPoint.getArgs();直接获取方法参数数组
后置通知JoinPoint + 返回值参数public void afterReturningAdvice(JoinPoint joinPoint, Object result)返回值通过returning参数获取
异常通知JoinPoint + 异常参数public void afterThrowingAdvice(JoinPoint joinPoint, Throwable ex)异常对象通过throwing参数获取
环绕通知ProceedingJoinPointpjp.proceed()包含完整方法控制权
引介通知不直接传递参数(接口绑定)@DeclareParents通过接口实现间接关联

执行结果

前置通知:方法开始
参数值:参数1
环绕通知:方法执行前
方法参数:[参数1]
执行业务逻辑,参数:参数1
环绕通知:方法执行后
后置通知:方法正常返回
返回值:null
参数列表:[参数1]

前置通知:方法开始
环绕通知:方法执行前
方法参数:[]
执行无参业务逻辑
环绕通知:方法执行后
后置通知:方法正常返回
返回值:null
参数列表:[]

前置通知:方法开始
环绕通知:方法执行前
方法参数:[]
执行会抛异常的逻辑
异常通知:方法抛出异常
异常信息:模拟异常
异常发生时的参数:[]
环绕通知:捕获异常
捕获到异常:模拟异常

引介通知:记录审计日志

核心要点

  1. JoinPoint:所有通知(除环绕)都通过JoinPoint对象获取参数
  2. ProceedingJoinPoint:环绕通知特有的接口,支持手动执行目标方法
  3. 参数绑定:通过注解属性(如returning/throwing)声明额外参数
  4. 参数类型:参数类型需与目标方法参数匹配,可通过joinPoint.getSignature()获取方法元数据
  5. 引介通知:主要用于类型增强,不直接参与参数传递

相关文章:

  • 【数据结构】哈夫曼树
  • 74. Linux设备树详解
  • 基于springboot课程学习与互动平台(源码+lw+部署文档+讲解),源码可白嫖!
  • SQL注入点判断数据库类型
  • 从“制造”到“智造”:生产线自动检测的技术变革与实践
  • 【力扣hot100题】(017)矩阵置零
  • 火山引擎智能数据洞察 ChatBI 适配 DeepSeek-R1 及 DeepSeek-V3
  • 【商城实战(75)】数据分析指标体系搭建:从0到1的技术指南
  • 基于Halcon仿VM流程列表的执行效果
  • 深入解析MapReduce工作流程:从核心原理到实战优化
  • 第五十二章 Spring之再进一步——Boot
  • 深度神经网络全解析:原理、结构与方法对比
  • MySQL-复制表的两种常见方式
  • AI日报 - 2025年03月28日
  • c++ - 右击一个cpp文件,但是编译菜单项是灰的
  • 【Ubuntu常用命令】
  • 【开题报告+论文+源码】基于SSM的智能驾校预约管理系统
  • leetcode160.相交链表
  • Three.js 实现四元数(Quaternion)与常用运算
  • 树莓派使用USB摄像头与TFLite实现目标检测的完整指南
  • 网站突然打不开了/提高网站排名
  • 学校网站建设模板/优化关键词具体要怎么做
  • 网站建设进展情况汇报/百中搜
  • 济南 网站建设/线上线下整合营销方案
  • 有没有做的很炫的科技型网站/seo下拉优化
  • 网站建设产品介绍/百度关键词搜索引擎