java注解本身不实现权限控制,需结合aop、拦截器或spring security等解析执行校验;自定义@requirepermission注解支持角色、权限码等元数据,通过aop切面读取并比对用户权限,不通过抛accessdeniedexception;可集成spring security的@preauthorize或自定义permissionevaluator增强表达能力;须注意运行时保留、切面启用、缓存更新及类级别注解继承等陷阱。

Java 中注解本身不直接实现权限控制,它只是元数据标记;真正的细粒度权限控制需要结合 AOP(如 Spring AOP 或 AspectJ)、拦截器(如 Spring MVC 拦截器)、或安全框架(如 Spring Security)来解析注解并执行校验逻辑。
定义自定义权限注解
先声明一个运行时保留、可用于方法或类的注解,携带角色、权限码、操作类型等信息:
@Target({ElementType.METHOD, ElementType.TYPE})<br>@Retention(RetentionPolicy.RUNTIME)<br>@Documented<br>public @interface RequirePermission {<br> String value() default ""; // 权限标识,如 "user:delete"<br> String[] roles() default {}; // 允许的角色,如 {"ADMIN", "MANAGER"}<br> String[] permissions() default {}; // 更细粒度的权限码(可与 value 互斥或补充)<br> boolean requireAll() default false; // 是否要求同时满足所有权限<br>}
用 AOP 拦截并校验权限
编写切面,在目标方法执行前读取注解、获取当前用户身份、判断是否授权:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 使用 @Around 切入带有
@RequirePermission的方法 - 从
SecurityContextHolder(Spring Security)或自定义上下文获取当前用户及角色/权限集合 - 解析注解中的
roles()和permissions(),按业务规则比对(例如:用户拥有任一允许角色,且具备全部 required 权限) - 不通过则抛出
AccessDeniedException,由全局异常处理器返回 403
配合 Spring Security 增强表达能力
Spring Security 原生支持注解式权限(如 @PreAuthorize),可直接写 SpEL 表达式:
@PreAuthorize("hasRole('ADMIN') and hasAuthority('user:delete')")<br>public void deleteUser(Long id) { ... }
若需复用自定义逻辑,可将校验封装为 SpEL 方法注入到表达式中,或继承 PermissionEvaluator 实现自己的权限决策器,再在 @PreAuthorize 中调用 hasPermission()。
避免常见陷阱
- 注解未加
@Retention(RUNTIME)→ 运行时无法反射读取 - 切面未启用或优先级冲突 → 权限检查被跳过
- 用户权限缓存未及时更新 → 修改角色后仍能访问旧资源
- 忽略类级别注解继承 → 在 Controller 类上标注后,子方法未自动生效(需在切面中显式处理
Method.isAnnotationPresent()和Class.getAnnotation())
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










