详解 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静态代理的资料请关注我们其它相关文章!

(0)

相关推荐

  • java 静态代理 动态代理深入学习

    一.代理模式 代理模式是常用的java设计模式,特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等. 代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务. 按照代理的创建时期,代理类可以分为两种: 静态代理:由程序员创建或特定工具自动生成源代码再对其编译.在程序运行前代理类的.class文件就已经存在了. 动态代理:在

  • Java设计模式之静态代理模式实例分析

    本文实例讲述了Java设计模式之静态代理模式.分享给大家供大家参考,具体如下: 代理模式,可以通过代理可以在原来的基础上附加一些其他的操作.静态代理模式相对比较简单无需再程序运行时动态的进行代理. 静态代理模式的角色: ① 抽象角色:真实对象和代理对象的共同接口.其中声明真实对象和代理对象需要做的事. ② 真实角色:实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色调用. ③ 代理角色:实现抽象角色,是真实角色的代理,通过真实角色的业务逻辑方法来实现抽象方法,并可以附加自己的操作. 下面提

  • 代理角色java设计模式之静态代理详细介绍

    Java动态代理模式 代理:一个角色代表别一个角色来实现某些特定的能功.    比如:生产商,中间商,客户这三者这间的关系              客户买产品不并直接与生产商打交道,也用不晓得产品是如何生产的,客户只与中间商打交道,而中间商便可以对产品行进一些包装,供提一些售后的服务. 代理模式有三个角色: 1. 抽象主题角色 2. 代理主题角色 3. 际实被代理角色 面下我们来个一个静态代理的现实. 我以一个坦克为例. 抽象主题角色:Moveable 复制代码 代码如下: package c

  • 浅谈Java代理(jdk静态代理、动态代理和cglib动态代理)

    一.代理是Java常用的设计模式,代理类通过调用被代理类的相关方法,并对相关方法进行增强.加入一些非业务性代码,比如事务.日志.报警发邮件等操作. 二.jdk静态代理 1.业务接口 /** * 业务接口 * @author pc * */ public interface UserService { // 增加一个用户 public void addUser(); // 编辑账户 public void editUser(); } 2.业务实现类 /** * 业务实现类 * @author pc

  • Java代理模式实例详解【静态代理与动态代理】

    本文实例讲述了Java代理模式.分享给大家供大家参考,具体如下: 即Proxy Pattern,23种java常用设计模式之一.代理模式的定义:对其他对象提供一种代理以控制对这个对象的访问. Java的代理模式是Java中比较常用的设计模式,分为2中代理:静态代理与动态代理(JDK动态代理和cglib动态代理) 优点: 职责清晰 真实角色只需关注业务逻辑的实现,非业务逻辑部分,后期通过代理类完成即可. 高扩展性 不管真实角色如何变化,由于接口是固定的,代理类无需做任何改动. 缺点: 很明显的一点

  • JAVA中的静态代理、动态代理以及CGLIB动态代理总结

    代理模式是java中最常用的设计模式之一,尤其是在spring框架中广泛应用.对于java的代理模式,一般可分为:静态代理.动态代理.以及CGLIB实现动态代理. 对于上述三种代理模式,分别进行说明. 1.静态代理 静态代理其实就是在程序运行之前,提前写好被代理方法的代理类,编译后运行.在程序运行之前,class已经存在. 下面我们实现一个静态代理demo: 静态代理 定义一个接口Target package com.test.proxy; public interface Target { p

  • JAVA 静态代理模式详解及实例应用

    JAVA 静态代理模式 代理模式(Proxy):为其他对象提供一种代理以控制对这个对象的访问. 代理模式说白了就是"真实对象"的代表,在访问对象时引入一定程度的间接性,因为这种间接性可以附加多种用途. 在这实现代码之前,先讲一个简单的生活故事,我们都知道我们周边有很多公司有房屋买卖或租赁的业务,比如链家(LianJia),但链家本身是不存在任何实际房屋资产的,他所售卖租赁的房屋均需要房屋产权所有人(HomeMaster)提供,才得以实现公司的房源需求:同时公司要的卖房租房业务均需要公司

  • Java静态代理和动态代理总结

    静态代理 第一种实现(基于接口): 1>接口 public interface Hello { void say(String msg); } 2>目标类,至少实现一个接口 public class HelloImpl implements Hello { public void say(String msg) { System.out.println("Hi,"+msg); } } 3>代理类(与目标类实现相同接口,从而保证功能一致) public class He

  • java设计模式—静态代理模式(聚合与继承方式对比)

    一.概述 1.目标:要在Tank的move()方法做时间代理及日志代理(可以设想以后还要增加很多代理处理),且代理间的顺序可活更换 2.思路: (1)聚合:代理类聚合了被代理类,且代理类及被代理类都实现了movable接口,则可实现灵活多变,具体看代码 (2)继承:继承不够灵活,随着功能需求增多,继承体系会非常臃肿.具体看代码 二.代码 1.Movable.java 2.Tank.java 3.TankTimeProxy.java 4.TankLogProxy.java 5.Tank2Time.

  • 深入解析java中的静态代理与动态代理

    java编码中经常用到代理,代理分为静态代理和动态代理.其中动态代理可以实现spring中的aop. 一.静态代理:程序运行之前,程序员就要编写proxy,然后进行编译,即在程序运行之前,代理类的字节码文件就已经生成了 被代理类的公共父类 复制代码 代码如下: package staticproxy;public abstract class BaseClass {    public abstract void add();} 被代理类 复制代码 代码如下: package staticpro

随机推荐