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();
  }
}

 

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

 

posted @ 2021-01-23 20:12  Master_Sun  阅读(97)  评论(0编辑  收藏  举报