面试
代理模式是一种结构型设计模式,核心思想是在不改变原始对象的前提下,通过一个代理对象来控制对原始对象的访问,可以在调用前后加点料,比如权限校验、日志记录、缓存等。
这个模式在业务开发中太常见了。Spring AOP 就是基于动态代理实现的,你写的@Transactional、@Async、@Cacheable这些注解能生效,底层都是代理在干活。RPC 框架也是靠动态代理,让调用远程方法跟调本地方法一样丝滑,Dubbo、gRPC 都是这个套路。
代理模式的结构很简单:客户端不直接调真实对象,而是调代理对象,代理对象内部持有真实对象的引用,在调用真实对象方法前后可以插入额外逻辑。
代理模式主要用在这几个场景:
- 访问控制:调方法前先检查权限,没权限直接拦住
- 延迟加载:真实对象创建成本高,用代理先顶着,真正用到时才初始化
- 远程代理:把网络通信细节封装在代理里,客户端以为在调本地方法
- 日志监控:统一在代理层记录方法调用耗时、参数、异常,不用每个方法都加代码
// 接口interfaceUserService{voidsave(Useruser);}// 真实对象classUserServiceImplimplementsUserService{publicvoidsave(Useruser){System.out.println("保存用户: "+user.getName());}}// 代理对象:加了日志和耗时统计classUserServiceProxyimplementsUserService{privateUserServicetarget;publicUserServiceProxy(UserServicetarget){this.target=target;}publicvoidsave(Useruser){longstart=System.currentTimeMillis();System.out.println("开始调用 save 方法");target.save(user);// 调真实对象System.out.println("调用结束,耗时: "+(System.currentTimeMillis()-start)+"ms");}}