详解 Java静态代理

 更新时间:2020年08月18日 11:34:31   作者:弗兰克的猫  
这篇文章主要介绍了 Java静态代理的相关资料,帮助大家更好的理解和学习Java代理的知识,感兴趣的朋友可以了解下

  今天要介绍的是一个Java中一个很重要的概念——代理。

  什么是代理?联系生活想想看,代理似乎并不陌生,最形象的代表便是经纪人,明星一般都有经纪人,经纪人作为中间人,负责代理明星的相关事宜,比如说,有人要请明星去唱歌表演,一般不会直接跟明星联系,而是联系他的经纪人,他的经纪人来负责安排行程,而真正唱歌表演的还是明星本人,经纪人仅仅作为一个附加物存在。

  在Java中,代理也是这样的概念,来看个栗子:

  先来创建一个明星类Stars:

public class Stars implements IStars{
  private String name;

  public Stars(String name) {
    this.name = name;
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public void sing(){
    System.out.println(getName() + " 唱了一首歌.");
  }

  public void dance(){
    System.out.println(getName() + " 跳了一支舞.");
  }
}

  这是相应的接口:

public interface IStars {
  void sing();
  void dance();
}

  现在创建一个代理类:

public class StarsProxy implements IStars{
  //保存接收的代理对象
  private IStars stars;

  public StarsProxy(IStars stars){
    this.stars = stars;
  }

  @Override
  public void sing() {
    System.out.println("我是代理,我收到了唱歌请求。");
    stars.sing();
    System.out.println("唱歌完毕");
  }

  @Override
  public void dance() {
    System.out.println("我是代理,我收到了跳舞请求。");
    stars.dance();
    System.out.println("跳舞完毕");
  }
}

  来测试一下:

public class Test {
  public static void main(String[] args){
    //创建目标对象
    IStars stars = new Stars("Frank");//代理对象,把目标传给代理对象,建立关系
    IStars starsProxy = new StarsProxy(stars);
    starsProxy.sing();
    starsProxy.dance();
  }
}

  运行结果:

我是代理,我收到了唱歌请求。
Frank 唱了一首歌.
唱歌完毕
我是代理,我收到了跳舞请求。
Frank 跳了一支舞.
跳舞完毕

  我们可以看到,实际上代理类只是保存了Stars类的一个实例,因为实现的是相同的接口,StarsProxy类必须实现需要代理的Stars类的方法,比如这里的dance和sing,而这个接口正是链接两者的关键,因为实现接口就代表必定存在接口中声明的方法。

  那么,为什么要使用代理呢?

  其实主要目的是为了扩展原有类的功能,想想看,如果那个Stars类不是你写的,而是别人写的,现在要将原有的sing或者dance方法进行改造,比如需要统计唱歌和跳舞的次数,次数大于10则不进行该操作直接返回,这时候用代理就很好实现了,来把代理类稍作修改:

public class StarsProxy implements IStars{
  //保存接收的代理对象
  private IStars stars;
  //保存sing和dance的次数
  private int num;

  public StarsProxy(IStars stars){
    this.stars = stars;
  }

  @Override
  public void sing() {
    if (!ifWork()) {
      return;
    }
    System.out.println("我是代理,我收到了唱歌请求。");
    stars.sing();
    System.out.println("唱歌完毕");
  }

  @Override
  public void dance() {
    if (!ifWork()) {
      return;
    }
    System.out.println("我是代理,我收到了跳舞请求。");
    stars.dance();
    System.out.println("跳舞完毕");
  }

  /**
   * 是否继续工作
   * @return 是返回true,否则返回false
   */
  private boolean ifWork(){
    if (num > 3){
      System.out.println("明星今天已经很累了,明天再来吧。");
      return false;
    }else {
      num++;
      return true;
    }
  }
}

  修改一下测试类:

public class Test {
  public static void main(String[] args){
    //创建目标对象
    Stars stars = new Stars();
    stars.setName("Frank");

    //代理对象,把目标传给代理对象,建立关系
    StarsProxy starsProxy = new StarsProxy(stars);
    for (int i = 0;i < 5; i++){
      starsProxy.sing();
    }
  }
}

  测试结果如下:

我是代理,我收到了唱歌请求。
Frank 唱了一首歌.
唱歌完毕
我是代理,我收到了唱歌请求。
Frank 唱了一首歌.
唱歌完毕
我是代理,我收到了唱歌请求。
Frank 唱了一首歌.
唱歌完毕
我是代理,我收到了唱歌请求。
Frank 唱了一首歌.
唱歌完毕
明星今天已经很累了,明天再来吧。

  看,简单粗暴。

  但其实并没有多少干货,这里仅仅是一种代理的思想,用这种思想可以比较方便的在不直接修改原有类的前提下对原有类的方法进行扩展。为某个对象提供一个代理,以控制对这个对象的访问。 代理类和委托类有共同的父类或父接口,这样在任何使用委托类对象的地方都可以用代理对象替代。代理类负责请求的预处理、过滤、将请求分派给委托类处理、以及委托类执行完请求后的后续处理。可以使业务类只关注业务逻辑本身,保证了业务类的重用性,这也是代理的共有优点。

  但是限制也显而易见:

  1.代理类需要跟被代理类实现相同的接口,这样才能一起向上转型后实现多态。

  2.当被代理的类需要进行的扩展增多时,管理会变得更加困难,之后对被代理类的修改,需要同时修改代理类,增加了修改成本。

  所以不要为了使用而使用,应用在合适的场景才能发挥它真正的作用。

  至此,本篇讲解完毕,欢迎大家继续关注!

以上就是详解 Java静态代理的详细内容,更多关于Java静态代理的资料请关注脚本之家其它相关文章!

相关文章

  • Java中实现双数组Trie树实例

    Java中实现双数组Trie树实例

    这篇文章主要介绍了Java中实现双数组Trie树实例,双数组Trie就是一种优化了空间的Trie树,本文给出了实现代码、测试代码和测试结果,需要的朋友可以参考下
    2015-01-01
  • java JVM-clinit指令实现原理面试精讲

    java JVM-clinit指令实现原理面试精讲

    这篇文章主要介绍了java JVM-clinit指令实现原理面试精讲,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-10-10
  • Java中线程安全有哪些实现思路

    Java中线程安全有哪些实现思路

    在 Java 多线程编程中,线程安全是一个非常重要的概念,本文主要介绍了Java中线程安全有哪些实现思路,非常具有实用价值,需要的朋友可以参考下
    2023-05-05
  • Spring学习之依赖注入的方法(三种)

    Spring学习之依赖注入的方法(三种)

    本篇文章主要介绍了Spring学习之依赖注入的方法(三种),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-07-07
  • java和Spring中观察者模式的应用详解

    java和Spring中观察者模式的应用详解

    这篇文章主要介绍了java和Spring中观察者模式的应用,,具有一定的参考价值,感兴趣的可以了解一下,希望能够给你带来帮助
    2021-10-10
  • Java实现上传和下载功能(支持多个文件同时上传)

    Java实现上传和下载功能(支持多个文件同时上传)

    这篇文章主要介绍了Java实现上传和下载功能,支持多个文件同时上传,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-12-12
  • springboot表单提交之validator校验

    springboot表单提交之validator校验

    在前台表单验证的时候,通常会校验一些数据的可行性,比如是否为空,长度,身份证,邮箱等等,这篇文章主要给大家介绍了关于springboot表单提交之validator校验的相关资料,需要的朋友可以参考下
    2021-05-05
  • Java实现MD5加密的方式与实例代码

    Java实现MD5加密的方式与实例代码

    MD5加密是一种常见的加密方式,我们经常用在保存用户密码和关键信息上。那么它到底有什么,又什么好处呢,会被这么广泛的运用在应用开发中
    2021-10-10
  • Mybatis分解式查询使用方法

    Mybatis分解式查询使用方法

    这篇文章主要介绍了Mybatis分解式查询使用方法,分解式查询就是将一条Sql语句拆分成多条。在 MyBatis 多表查询中,使用连接查询时一个 Sql 语句就可以查询出所有的数据
    2023-04-04
  • Java中的类加载与类卸载方式

    Java中的类加载与类卸载方式

    这篇文章主要介绍了Java中的类加载与类卸载方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-12-12

最新评论