学习设计模式-结构型-代理模式

333 阅读1分钟

代理模式

他是在不改变原始类(被代理类)代码情况下,通过引入代理类来给原始添加功能。

动态代理

我们不需要事先为每个原始类编写代理类,然后在运行的时候,动态的创建原始类的代理类,然后在系统中使用代理类代替原始类。Java动态代理底层依赖java的反射语法。
例子:创建一个接口运行时间计数器。
原始方式:

public class MetricsCollectorProxy {

   //计数统计类
   private MetricsCollector collector;

   public MetricsCollectorProxy() {
      this.collector = new MetricsCollector();
   }

   public Object createProxy(Object proxiedObject) {
      Class<?>[] interfaces = proxiedObject.getClass().getInterfaces();
      DynamicProxyHandler handler = new DynamicProxyHandler(proxiedObject);
      return Proxy.newProxyInstance(proxiedObject.getClass().getClassLoader(), interfaces, handler);
   }

   private class DynamicProxyHandler implements InvocationHandler {

      private Object proxiedObject;

      public DynamicProxyHandler(Object proxiedObject) {
         this.proxiedObject = proxiedObject;
      }

      @Override
      public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
         long start = System.currentTimeMillis();
         Object result = method.invoke(proxiedObject, args);
         long end = System.currentTimeMillis();
         long run = end - start;
         String apiName = proxiedObject.getClass().getName() + ":" + method.getName();
         RequestInfo info = new RequestInfo(apiName, run);
         collector.recordRequest(info);
         return result;
      }
   }
}
//使用
MetricsCollectorProxy proxy = new MetricsCollectorProxy();
IVersionController controller = (IVersionController) proxy.createProxy(new VersionController());

实际上Spring AOP底层就是就是基于动态代理。 springboot切面AOP简单使用 - 掘金 (juejin.cn)

使用

代理模式使用场景很多,比如业务系统中开发非功能性需求,比如监控、统计、鉴权、限流、事务、幂等、日志等。除此之外还可用在RPC、缓存等应用场景中。