Java代理模式能同时解决权限控制和延迟加载问题,核心是代理对象接管访问并在调用前后插入校验或按需初始化逻辑;通过统一接口(Subject)、真实对象(RealSubject)专注业务、代理对象(Proxy)持空引用并首次调用时创建,实现透明性、控制性与解耦性。

Java代理模式能同时解决权限控制和延迟加载两个关键问题,核心在于让代理对象接管对真实业务对象的访问,在调用前后插入校验逻辑或按需初始化。
明确抽象接口与角色分工
先定义统一的业务接口(Subject),让真实对象和代理对象都实现它。客户端只依赖这个接口,不感知背后是真实对象还是代理——这是透明性的基础。
- 接口要覆盖所有需要控制的方法,比如 viewProfile()、updateProfile()
- 真实对象(RealSubject)专注实现具体业务,不掺杂权限或加载逻辑
- 代理对象(Proxy)持有真实对象引用(初始为 null),并在真正需要时才创建
用保护代理实现细粒度权限控制
针对不同用户身份,可设计多个代理子类,各自封装不同的访问规则。例如:用户本人可读写,他人仅可读。
- 在代理的每个方法入口处检查调用者身份,如 if (!currentUser.equals(targetUser)) throw new AccessDeniedException();
- 避免把权限逻辑散落在真实对象里,保持业务干净
- 权限判断可复用 Spring Security 的 Authentication 或自定义上下文工具类
用虚拟代理触发延迟加载
当真实对象构造开销大(如加载高清图、查询数据库、解析大文件),代理可在首次调用时才初始化它。
立即学习“Java免费学习笔记(深入)”;
- 代理内部声明 private RealSubject realSubject;,初始为 null
- 每次调用业务方法前,先判断 if (realSubject == null) realSubject = new RealSubject();
- 后续调用直接委托,避免重复初始化
- 适合 MyBatis 的 lazy loading、图片占位加载、远程配置缓存等场景
组合使用增强实用性
一个代理可以同时承担权限校验和延迟加载,只需在方法中按顺序执行检查与初始化逻辑。
- 比如 display() 方法先验证权限,再检查并加载真实对象,最后转发调用
- 还可叠加日志记录、耗时统计、异常兜底等横切逻辑,全部集中在代理中
- Spring AOP 底层就是基于动态代理,但手写静态代理更可控、更易调试


















