Java可重复注解需通过@Repeatable与容器注解配对定义,运行时须用getAnnotationsByType()获取,结合AOP与动态校验逻辑实现灵活权限控制。

Java可重复注解不是“多写几次就生效”,而是通过@Repeatable配合容器注解,让多个同类型规则能自然叠加在同一个方法上,再由统一逻辑解析执行——这是实现灵活权限校验的关键扩展能力。
必须配对定义:业务注解 + 容器注解
要支持重复使用,不能只写一个注解。必须两步到位:
- 业务注解(如
@Role)加上@Repeatable(Roles.class),括号里填容器类名 - 容器注解(如
@Roles)必须满足:@Retention和@Target与业务注解完全一致;value字段类型为业务注解数组,且名称严格为value - 例如:
@Roles里写Role[] value();,少一个字母或类型不对,编译就报错
运行时获取:用getAnnotationsByType(),别用getAnnotation()
写了两个@Role("ADMIN") @Role("EDITOR"),反射时容易拿错:
-
method.getAnnotation(Role.class)→ 返回null(因为实际存在的是容器@Roles) -
method.getAnnotation(Roles.class)→ 能拿到容器实例,但需手动取.value() -
method.getAnnotationsByType(Role.class)→ ✅ 直接返回Role[]数组,最简洁可靠
权限校验链中真正起作用的环节
注解只是标记,校验逻辑才是核心。常见结构如下:
立即学习“Java免费学习笔记(深入)”;
- AOP切面拦截带注解的方法(如
@Before("@annotation(Role)")或更稳妥的@Around("@annotation(PermissionCheck)")) - 从
JoinPoint中提取真实Method对象(注意CGLIB代理下别误用joinPoint.getTarget().getClass().getMethod(...)) - 调用
method.getAnnotationsByType(Role.class)拿到所有角色声明 - 结合当前用户角色列表做匹配:支持OR(任一满足)、AND(全部满足)等策略
结合权限模型做语义升级
单纯重复角色还不够,可进一步承载业务约束:
- 定义
@PositionRedLine(value="SECURITY_OFFICER", actions={"EXPORT_LOG"}),把岗位+操作码+拒绝提示打包成一条红线 - 多个
@PositionRedLine连续标注,表达“只要命中任一岗位,就触发对应动作限制” - 校验时不再只比对角色字符串,而是动态检查用户实时岗位、当前请求操作码、上下文敏感条件(如是否在生产环境)


















