Bootstrap

当静态代理碰上Java Runnable接口 (代理的Thread)

前段时间找工作时,复习了一下设计模式,当时在写静态代理demo时想偷个懒,便用Runnable做抽象主题接口,于是就发现了些新东西,给大家分享一下。

代理模式简介

        代理模式是一种设计模式,它为一个对象提供一个代理或替代,以便控制对该对象的访问。代理模式允许我们在不直接访问原始对象的情况下与它进行交互,也可以添加额外的功能或修改其行为。

        Java中的代理按照代理类生成时机不同又分为静态代理和动态代理。静态代理代理类在编译期就生成,而动态代理代理类则是在Java运行时动态生成。动态代理又有JDK代理和CGLib代理两种。

 代理模式结构

代理(Proxy)模式分为三种角色:

  • 抽象主题(Subject)类: 通过接口或抽象类声明真实主题和代理对象实现的业务方法。
  • 真实主题(Real Subject)类: 实现了抽象主题中的具体业务,是代理对象所代表的真实对象,是最终要引用的对象。
  • 代理(Proxy)类 : 提供了与真实主题相同的接口,其内部含有对真实主题的引用,它可以访问、控制或扩展真实主题的功能。

例如飞机票,可以通过 “携程APP” 、“旅行社”代理 “航空公司” 进行机票的销售。

  • “卖机票的能力”就是抽象主题类,“国航卖票” 和 “东航卖票” 就是 真实主题类,“携程APP” 、”旅行社“ 就是代理类

我的静态代理demo

  • 抽象主题类Runnable
  • 真实主题类ProxyItem 
  • 代理类StaticProxy
/**
 * 被代理对象
 */
public class ProxyItem implements Runnable  {


  @Override
  public void run() {
    System.out.println("我是被代理对象:::我出来表演了");
  }
}
/**
 * 静态代理类
 */
public class StaticProxy implements Runnable {
  private  Runnable item ;

  public StaticProxy(Runnable item) {
    this.item = item;
  }

  @Override
  public void run() {
    System.out.println("我要开始代理了==》");
    item.run();
    System.out.println("我要完成代理了《==");
  }

}
//测试代码
  public static void main(String[] args) {
    StaticProxy staticProxy = new StaticProxy(new ProxyItem());
    staticProxy.run();
  }

测试结果 

 

 回头看看StaticProxy类

大家再看看StaticProxy类,是否感觉有些熟悉?

还不不熟悉?那要不把StaticProxy换个名字为Thread。

这下你该猜到我要说什么了吧?

还没猜到?那我再附上一段Thead 类的源码给看官瞧瞧

public class Thread implements Runnable {
    //省略阅读无关代码....

    private Runnable target;

    //省略阅读无关代码...

    //参数为Runnable的构造函数
    public Thread(Runnable target) {
        //下面这句与阅读相关逻辑为:this.target = target;
        init(null, target, "Thread-" + nextThreadNum(), 0);
    }

    //省略阅读无关代码...

    public void run() {
        if (target != null) {
            target.run();
        }
    }

    //省略阅读无关代码...

}

对比代理类StaticProxy和Thread

//简化后只剩一个Runnable 参数构造函数的Thread类
public class Thread implements Runnable {
    private Runnable target;
    public Thread(Runnable target) {
        this.target = target;
    }
    public void run() {
        target.run();
    }
}


//简化后的代理类StaticProxy
public class StaticProxy implements Runnable {
  private  Runnable item ;

  public StaticProxy(Runnable item) {
    this.item = item;
  }

  public void run() {
    item.run();
  }

}

public class ProxyItem implements Runnable  {
  public void run() {
   //
  }
}

 代理类StaticProxy 实现和传入Runnable 构造Thead()的实现完全一样呀,也就是说Thread类实现了Runable接口进行了代理

再简短点,Thread类使用了静态代理模式

      

;