zoukankan      html  css  js  c++  java
  • spring 梳理10--代理模式 静态代理、动态代理、基于接口的动态代理----JDK动态代理   基于类的动态代理--cglib

    1、代理模式回顾

    代理模式,使得在IOC中实现AOP变得可能。

    代理模式分为静态代理和动态代理。代理的核心功能是方法增强

    (1)静态代理

    静态代理角色分析

    抽象角色 : 一般使用接口或者抽象类来实现

    真实角色 : 被代理的角色

    代理角色 : 代理真实角色 ; 代理真实角色后 , 一般会做一些附属的操作 .

    客户 : 使用代理角色来进行一些操作

    代码实现

    写一个接口,即抽象角色

    public interface Singer {
      /**
      * 歌手的统一方法
      */
      void sing();
    }

    Host . java 即真实角色

    public class MaleSinger implements Singer {
      @Override
      public void sing() {
      System.out.println("我要唱歌了!!!");
      }
    }

    Proxy . java 即代理角色

    public class Agent implements Singer {
      private Singer singer;
      /**
      * 经纪人必须代理一个歌手
      * @param singer
      */
      Agent(Singer singer){
        this.singer = singer;
      }
      @Override
      public void sing() {
        System.out.println("经纪人要把把关,看看这个演出合适不合适!");
        singer.sing();
        System.out.println("歌手唱完歌,经纪人去收钱!");
      }
    }

    Client . java 即客户

    public class Client {
    public static void main(String[] args) {
      Singer luhan = new MaleSinger();
      Agent zhangsan = new Agent(luhan);
      zhangsan.sing();
      }
    }

    分析:在这个过程中,你直接接触的就是鹿晗的经济人,经纪人在鹿晗演出的前后跑前跑后发挥了巨大的作用。

    优点

    鹿晗还是鹿晗,没有必要为了一下前置后置工作改变鹿晗这个类

    公共的统一问题交给代理处理,更加符合开闭原则,单一原则

    公共业务进行扩展或变更时,可以更加方便

    缺点 :

    每个类都写个代理,麻烦

    (2)动态代理

    动态代理的角色和静态代理的一样 .

    动态代理的代理类是动态生成的 . 静态代理的代理类是我们提前写好的

    动态代理分为两类 : 一类是基于接口动态代理 , 一类是基于类的动态代理

    •   基于接口的动态代理----JDK动态代理
    •   基于类的动态代理--cglib
    •   现在用的比较多的是 javasist 来生成动态代理 . 百度一下javasist
    •   我们这里使用JDK的原生代码来实现,其余的道理都是一样的!

    JDK的动态代理需要了解两个类  InvocationHandler 和 Proxy(打开JDK帮助文档看看)

      【InvocationHandler:调用处理程序】

      【Proxy : 代理】

    代码实现

    抽象角色和真实角色和之前的一样! 还是歌星和男歌星

    ProxyInvocationHandler. java 即代理角色

    public class Agent implements InvocationHandler {
      private Singer singer;
      /**
      * 设置代理的经济人
      * @param singer
      */
      public void setSinger(Singer singer) {
        this.singer = singer;
      }
      @Override   
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {     System.out.println("---------------经纪人把把关--------------");
        //一种反射,调用的方法是什么,method就是什么,传什么参数,args就是什么参数
        Object returnObj
    = method.invoke(singer, args);     System.out.println("---------------唱完了收收钱------------------------");     return returnObj;   }   /**   * 获取一个代理对象   * @return   */   public Object getProxy(){     return Proxy.newProxyInstance(this.getClass().getClassLoader(),     new Class[]{Singer.class},this);   } }

    Client . java

    public class Client {
      public static void main(String[] args) {
        MaleSinger luhan = new MaleSinger();
        Agent agent = new Agent();
        agent.setSinger(luhan);
        Singer singer = (Singer)agent.getProxy();
        singer.sing();
      }
    }

    核心:一个动态代理 , 一般代理某一类业务 , 一个动态代理可以代理多个类,代理的是接口!

  • 相关阅读:
    Java (三)APACHE Commons IO 常规操作
    JavaFX FileChooser文件选择器,缓存上一次打开的目录
    JavaFX FileChooser文件选择器、DirectoryChooser目录选择器
    javaFX 在窗口的标题栏显示当前时间,1秒更新一次时间
    Java 实现截屏
    composer安装包的时候触发PHP fatal error,提示允许的内存耗光
    箭头函数
    js中的寄生组合继承
    构造函数的原型
    在string.replace中使用具名组匹配
  • 原文地址:https://www.cnblogs.com/Master-Sun/p/14318793.html
Copyright © 2011-2022 走看看