Java自定义注解同时标注类和方法时方法注解被忽略问题排查
问题原因
- 切点参数绑定存在优先级冲突
你定义的切点逻辑为@annotation(customAuthorize) || @within(customAuthorize),当类和方法同时标注@CustomAuthorize注解时,Spring AOP的参数绑定机制会优先匹配@within对应的类级别注解,最终传入通知方法的customAuthorize实例是类上的注解对象,方法级的注解不会被传入。 - 切面逻辑缺少优先级判断
你当前的实现完全依赖切点绑定的注解参数,没有主动校验方法层是否存在注解,也没有实现「方法注解优先级高于类注解」的默认规则。另外你写的Objects.isNull(customAuthorize)判断永远不会生效,只要触发切点,绑定的注解参数就不会为空,该分支代码完全不会执行。
修复方案
最优方案是取消切点的注解参数绑定,在环绕通知中主动获取对应层级的注解,自行控制优先级:
@Aspect @Component public class CustomAnnotationAspect { @Autowired CustomAuthorizationImpl authBean; // 注意把com.xxx替换为你自己项目中CustomAuthorize注解的实际包路径 @Pointcut("@within(com.xxx.CustomAuthorize) || @annotation(com.xxx.CustomAuthorize)") public void pointcutForCustomAnnotation() { } @Around("pointcutForCustomAnnotation()") public Object customAspect(ProceedingJoinPoint pjp) throws Throwable { MethodSignature signature = (MethodSignature) pjp.getSignature(); // 优先取方法上的注解 CustomAuthorize customAuthorize = signature.getMethod().getAnnotation(CustomAuthorize.class); // 方法上无注解时再取类上的注解 if (customAuthorize == null) { customAuthorize = pjp.getTarget().getClass().getAnnotation(CustomAuthorize.class); } // 执行原有权限校验逻辑即可 ExpressionParser elParser = new SpelExpressionParser(); if (!customAuthorize.permission().isBlank()) { // 原有权限校验逻辑 } return pjp.proceed(); } }
修改后逻辑会优先读取方法上的注解,方法上未标注时才会读取类上的注解,完全覆盖单独标注类、单独标注方法、同时标注三种场景,不会出现注解被覆盖的问题。
内容的提问来源于stack exchange,提问作者Phuc Nguyen
相关产品推荐
相关产品推荐

