解决什么问题
当需要在不修改一个类的前提下,对类的方法进行功能增强时,就需要使用代理模式。或者说 通过引入代理类来给原始类附加功能
应用场景
代理模式常用在业务系统中开发一些非功能性需求,比如:监控、统计、鉴权、限流、事务、幂等、日志。我们将这些附加功能与业务功能解耦,放到代理类统一处理,让程序员只需要关注业务方面的开发。除此之外,代理模式还可以用在 RPC、缓存等应用场景中。
如何实现的
静态代理,代理类
// 原始类 public class User { public String login(String userId) { // to do things // ...... return "登录成功" ; } } // 代理类 继承 原始类 public class UserProxy extends User { @Override public String login(String userId) { long startTime = System.currentTimeMillis(); // 调用父类方法 String str = super .login(userId); long endTime = System.currentTimeMillis(); if (endTime - startTime > 20 ) { // 打印报警日志,登录操作耗时过长 } return str; } } // 如何使用 public static void main(String[] args) { User user = new UserProxy(); user.login( "123456" ); } |
静态代理,代理接口
// 接口 public interface UserInterface { public String login(String userId); } // 原始类 public class User implements UserInterface{ @Override public String login(String userId) { // to do things // ...... return "登录成功" ; } } // 代理类 public class UserProxy implements UserInterface { private User user; public UserProxy(User user) { this .user = user; } @Override public String login(String userId) { long startTime = System.currentTimeMillis(); // 调用原始类方法 String str = user.login(userId); long endTime = System.currentTimeMillis(); if (endTime - startTime > 20 ) { // 打印报警日志,登录操作耗时过长 } return str; } } // 如何使用 public static void main(String[] args) { UserInterface user = new UserProxy( new User()); user.login( "123456" ); } |
动态代理,代理接口
Java语言提供了支持动态代理的功能,但是只能基于接口。
动态代理,代理类
可以使用 cglib 代理类,而无需继承原始类