Spring AOP中@AfterReturning获取参数时出现空指针异常问题
问题原因
Spring AOP中,若@Around切面仅修改原参数数组但未通过proceed(modifiedArgs)传递修改后的参数,后续@AfterReturning/@AfterThrowing切面会拿到原始参数引用;同时切面执行顺序未明确时,参数修改切面可能在@Audited切面之后执行,导致审计切面获取未修改的参数,进而出现NullPointerException。
解决方案
1. 确保Around切面传递修改后的参数
在处理@Tester、@Random注解的Around切面中,修改参数后必须调用proceed(modifiedArgs)传递新参数数组,而非直接修改原数组后调用无参proceed():
@Around("@annotation(org.springframework.web.bind.annotation.GetMapping) && execution(* *(..))") public Object modifyParams(ProceedingJoinPoint joinPoint) throws Throwable { Object[] args = joinPoint.getArgs(); MethodSignature signature = (MethodSignature) joinPoint.getSignature(); Parameter[] parameters = signature.getMethod().getParameters(); // 遍历处理带注解的参数 for (int i = 0; i < parameters.length; i++) { if (parameters[i].isAnnotationPresent(Tester.class)) { args[i] = "modified-tester-value"; } else if (parameters[i].isAnnotationPresent(Random.class)) { args[i] = "modified-random-value"; } } // 传递修改后的参数给后续流程 return joinPoint.proceed(args); }
2. 明确切面执行顺序
用@Order注解指定优先级,让参数修改切面先执行,再执行@Audited相关切面:
- 参数修改切面标注
@Order(1) @Audited切面标注@Order(2)
3. 正确获取AfterReturning切面的参数
确保@AfterReturning切面在参数修改切面之后执行,直接通过JoinPoint.getArgs()即可获取修改后的参数:
@Aspect @Component @Order(2) public class AuditedAspect { @AfterReturning(pointcut = "@annotation(Audited)", returning = "result") public void afterReturning(JoinPoint joinPoint, Object result) { Object[] args = joinPoint.getArgs(); // 此处可正常获取修改后的参数 for (Object arg : args) { System.out.println("Audited 参数: " + arg); } } }
4. 校验切点匹配范围
确保参数注解切面的切点覆盖目标GetMapping方法,比如:
@Around("execution(* *(..)) && (@annotation(org.springframework.web.bind.annotation.GetMapping) || @annotation(org.springframework.web.bind.annotation.PostMapping))")
内容的提问来源于stack exchange,提问作者chunkynuggy
相关产品推荐
相关产品推荐

