Java接口结合代理模式实现权限控制,关键在于用统一接口定义行为契约,代理类与真实类实现同一接口并在方法调用前插入外置化权限校验逻辑,业务类专注实现、无感知安全细节。

Java 中接口结合代理模式实现权限访问控制,关键在于用接口统一行为契约,让代理类和真实业务类“看起来一样”,再由代理在方法调用前插入权限判断逻辑——客户端无感知,业务类不沾染权限代码。
定义清晰的业务接口
接口是整个代理结构的基石。它只声明需要受控的操作,不包含实现或状态细节。
- 所有要控制访问的方法(如 read()、delete()、update())必须出现在接口中
- 避免把权限字段、用户上下文等非业务内容放进接口,否则破坏职责分离
- 接口名建议体现领域语义,例如 DocumentService 而不是 IProxyable
真实对象专注业务逻辑
真实类只管“做什么”,不管“谁可以做”。它实现接口,但对权限一无所知。
- 例如 RealDocumentService 实现 DocumentService,只写文件读写逻辑
- 不引入 SecurityContext、Authentication 等安全相关依赖
- 便于单独单元测试,也支持未来替换为其他实现(如内存版、Mock版)
代理类封装权限校验逻辑
代理类也实现同一接口,内部持有真实对象引用,并在每个方法开头执行权限检查。
立即学习“Java免费学习笔记(深入)”;
- 校验可基于当前用户角色,例如 if (!hasRole("EDITOR")) throw new AccessDeniedException();
- 推荐复用已有安全机制,比如 Spring Security 的 SecurityContextHolder.getContext().getAuthentication()
- 权限规则尽量外置,例如从配置文件读取 delete → ["ADMIN"],而非硬编码在 if 判断里
- 失败时立即返回或抛异常,避免后续执行造成资源浪费(如已打开数据库连接)
灵活组合其他横切关注点
权限控制不是孤立的,代理天然适合叠加日志、监控、延迟加载等逻辑。
- 一个 SecuredDocumentProxy 可以先校验权限,再检查是否已初始化真实对象(虚拟代理),最后记录调用耗时
- 避免多个代理层层嵌套,优先在一个代理内按需编排逻辑顺序
- 若规则复杂(如按数据行级权限),可在代理中调用外部鉴权服务,而非自行解析表达式


















