Spring AOP 6.1+中无法获取Groovy类方法参数名的解决方案咨询
解决方案:Spring 6.1中AOP获取方法参数名的替代方案
核心问题原因
Spring 6.1移除了LocalVariableTableParameterNameDiscoverer,原有的MethodSignature.getParameterNames()依赖该实现,导致即使开启-parameters编译参数也可能返回null。当前Spring默认使用DefaultParameterNameDiscoverer,需主动适配该实现来获取参数名。
步骤1:确保编译时启用-parameters参数
这是反射获取参数名的基础,必须配置:
- Maven:在
pom.xml的maven-compiler-plugin中添加配置<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.11.0</version> <configuration> <source>17</source> <!-- 替换为你的JDK版本 --> <target>17</target> <parameters>true</parameters> <!-- 关键配置 --> </configuration> </plugin> - Gradle:在
build.gradle中添加compileJava { options.parameters = true } - IDEA:打开
File > Settings > Build, Execution, Deployment > Compiler > Java Compiler,勾选Store information about method parameters (usable via reflection)
步骤2:在切面中使用DefaultParameterNameDiscoverer获取参数名
不再依赖MethodSignature.getParameterNames(),手动通过Spring推荐的实现获取:
@Aspect @Component public class CustomAnnotationAspect { private final ParameterNameDiscoverer parameterNameDiscoverer = new DefaultParameterNameDiscoverer(); @Before("@annotation(customAnnotation)") public void handleSecurityLogic(JoinPoint joinPoint, CustomAnnotation customAnnotation) { MethodSignature signature = (MethodSignature) joinPoint.getSignature(); Method targetMethod = signature.getMethod(); // 获取参数名数组 String[] paramNames = parameterNameDiscoverer.getParameterNames(targetMethod); if (paramNames == null) { throw new IllegalStateException("无法获取方法参数名,请检查编译参数是否开启-parameters"); } Object[] methodArgs = joinPoint.getArgs(); // 示例:匹配注解中指定的projectId参数 int projectIdIdx = Arrays.asList(paramNames).indexOf(customAnnotation.projectIdParameter()); if (projectIdIdx != -1) { String projectId = (String) methodArgs[projectIdIdx]; // 执行你的安全校验逻辑 } // 示例:处理SpEL表达式(如#userEntity.id) SpelExpressionParser parser = new SpelExpressionParser(); EvaluationContext context = new StandardEvaluationContext(); for (int i = 0; i < paramNames.length; i++) { context.setVariable(paramNames[i], methodArgs[i]); } Object userId = parser.parseExpression(customAnnotation.userIdParameter()).getValue(context); // 基于userId的安全逻辑 } }
步骤3:解决偶发失效问题
- 强制清理构建缓存:执行
mvn clean install时,确保删除target目录,避免旧编译产物干扰 - IDEA运行配置检查:在
Run/Debug Configurations中,勾选Build project before running,确保每次运行前都重新编译 - 排查Bean冲突:检查Spring容器中是否存在自定义的
ParameterNameDiscovererBean,若有需确保其兼容DefaultParameterNameDiscoverer的逻辑
内容的提问来源于stack exchange,提问作者bytor99999
相关产品推荐
相关产品推荐

