JAVA 注解的框架封装

作者: 右耳菌 | 来源:发表于2022-04-18 01:04 被阅读0次

    一、代理模式

    代理模式(Proxy)为其他的对象提供一种代理,以控制对这个对象的访问。代理对象在客户端和目标对象之间起到中介的作用。

    1. 代理模式的作用
    • 在某些情况下,一个客户类不想或者不能直接引用一个委托对象,而代理类对象可以在客户类和委托对象之间起到中介的作用,其特征是代理类和委托类实现相同的接口。
    • 代理类除了是客户类和委托类的中介之外,我们还可以通过给代理类增加额外的功能来扩展委托类的功能,这样做我们只需要修改代理类而不需要再修改委托类,符合代码设计的开闭原则。
    图解代理模式
    2. 静态代理

    静态代理在使用时,需要定义接口或者父类,被代理对象与代理对象一起实现相同的接口或者是继承相同父类。

    • 一个例子
      1. 创建服务接口 GameFactory
      package cn.lazyfennec.proxydemo.service;
      
      public interface GameFactory {
      
          String make();
      
      }
      
      1. 创建Ps4GameFactory和GameBoyFactory实现GameFactory
      package cn.lazyfennec.proxydemo.real;
      
      import cn.lazyfennec.proxydemo.service.GameFactory;
      
      /**
       * @Author: Neco
       * @Description:
       * @Date: create in 2022/4/17 23:57
       */
      public class Ps4Factory implements GameFactory {
          @Override
          public String make() {
              return "ps4";
          }
      }
      
      package cn.lazyfennec.proxydemo.real;
      
      import cn.lazyfennec.proxydemo.service.GameFactory;
      
      /**
       * @Author: Neco
       * @Description:
       * @Date: create in 2022/4/18 0:08
       */
      public class GameBoyFactory implements GameFactory {
      
          @Override
          public String make() {
              return "game boy";
          }
      
      }
      
      1. 创建代理类NecoProxy
      package cn.lazyfennec.proxydemo.proxy;
      
      import cn.lazyfennec.proxydemo.service.GameFactory;
      
      /**
       * @Author: Neco
       * @Description:
       * @Date: create in 2022/4/18 0:04
       */
      public class NecoProxy implements GameFactory {
      
          GameFactory factory;
      
          public NecoProxy(GameFactory factory) {
              this.factory = factory;
          }
      
          @Override
          public String make() {
              doSomethingBefore();
              String make = factory.make();
              System.out.println(make);
              doSomethingAfter();
              return null;
          }
      
          // 售前服务
          private void doSomethingBefore() {
      
          }
      
          // 售后服务
          private void doSomethingAfter() {
      
          }
      
      }
      
      4、创建执行类
      package cn.lazyfennec.proxydemo.caller;
      
      import cn.lazyfennec.proxydemo.proxy.NecoProxy;
      import cn.lazyfennec.proxydemo.real.GameBoyFactory;
      import cn.lazyfennec.proxydemo.real.Ps4Factory;
      
      /**
       * @Author: Neco
       * @Description:
       * @Date: create in 2022/4/17 23:58
       */
      public class Tuhao {  
      
          public static void main(String[] args) { // 土豪要去购买,代理
      
              Ps4Factory ps4Factory = new Ps4Factory();
              NecoProxy necoProxy = new NecoProxy(ps4Factory);
              necoProxy.make();
      
              GameBoyFactory gameBoyFactory = new GameBoyFactory();
              necoProxy = new NecoProxy(gameBoyFactory);
              necoProxy.make();
          }  
      
      }
      
    • 静态代理总结
      1. 优点:不修改目标对象的功能前提下,对目标功能进行扩展。
      2. 缺点:因为代理对象需要与目标对象实现一样的接口,所以会有很多代理类被创建,类太多。同时一旦接口增加方法,目标与代理对象都要维护,增加维护成本。
    3. 动态代理
    • 代理类在程序运行时创建的代理方式被称为动态代理。

    • 这种情况下,代理类并不是在Java代码中定义的,而是在运行时根据我们在Java代码中的“指示”动态生成的。

    • 要点

      • proxy 代理对象 - 由它分配代理对象
      • InvocationHandler 标准化的代购流程
    • 一个例子

      1. 创建服务接口 GameFactory,与静态代理一致
      2. 创建Ps4GameFactory和GameBoyFactory实现GameFactory,与静态代理一致
      3. 创建代理类NecoDynamicProxy
      package cn.lazyfennec.proxydemo.proxy;
      
      import java.lang.reflect.InvocationHandler;
      import java.lang.reflect.Method;
      import java.lang.reflect.Proxy;
      
      /**
       * @Author: Neco
       * @Description:
       * @Date: create in 2022/4/18 0:34
       */
      public class NecoDynamicProxy implements InvocationHandler {  
      
          public Object target; // 被代理的对象
      
          public Object getTarget() {
              return target;
          }
      
          public void setTarget(Object target) {
              this.target = target;
          }
      
          public Object getProxy() { // 我只负责与总公司联系,不再去接触具体的店铺
              return Proxy.newProxyInstance(
                      target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
          }
      
          @Override
          public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
              doSomethingBefore();
              Object invoke = method.invoke(target, args);
              System.out.println(invoke);
              doSomethingAfter();
              return null;
          }
      
          // 售前服务
          private void doSomethingBefore() {
              System.out.println("pay");
          }
      
          // 售后服务
          private void doSomethingAfter() {
              System.out.println("is ok");
          }
      }
      
      1. 创建执行类
      package cn.lazyfennec.proxydemo.caller;
      
      import cn.lazyfennec.proxydemo.proxy.NecoDynamicProxy;
      import cn.lazyfennec.proxydemo.real.Ps4Factory;
      import cn.lazyfennec.proxydemo.service.GameFactory;
      
      /**
       * @Author: Neco
       * @Description:
       * @Date: create in 2022/4/18 0:43
       */
      public class TuhaoDynamic {  
      
          public static void main(String[] args) {
              NecoDynamicProxy proxy = new NecoDynamicProxy();
              Ps4Factory ps4Factory = new Ps4Factory();
              proxy.setTarget(ps4Factory);
              GameFactory factory = (GameFactory) proxy.getProxy();
              factory.make();
          }
      
      }
      
    4. 动态代理VS静态代理:
    • 静态代理类和委托类实现了相同的接口,代理类通过委托类实现了相同的方法。这样就出现了大量的代码重复。
    • 静态代理对象只服务于一种类型的对象,如果要服务多类型的对象。势必要为每一种对象都进行代理,静态代理在程序规模稍大时就无法胜任了。
    5. 更高级的封装
    • 加入 Spring Aop 和 Ioc

    相关文章

      网友评论

        本文标题:JAVA 注解的框架封装

        本文链接:https://www.haomeiwen.com/subject/kyflertx.html