美文网首页
设计模式之代理模式

设计模式之代理模式

作者: kgxl | 来源:发表于2018-06-26 00:09 被阅读0次

前言

        在说代理模式之前,我先说一下日常我们说的代理和被代理人,这东西就是我们常听到的律师帮人打官司,当发生纠纷的时候,自己也不懂法律啊,这咋办,总不能硬着头皮上吧,这时候就需要一个律师做你的代理,帮你打一波官司,而你就成为了被代理人
        在了解了代理和被代理人之后再来了解代理模式那就很方便了,只要记住代理就是做事的,被代理人只需要知道结果(其实就是过着懒人的生活,什么都不用操心)。
        Java中的代理模式分为两种:

静态代理
        这种代理模式从名字上来看就知道,静态静态,就是一开始规定好了,在这里就是代表是我们程序员自己根据需要被代理的类来创建的代理类,可能看着比较绕,上代码就很清楚了:

首先先来个IClassMethod接口,里面主要是抽象了代理类和被代理类共同的方法(你要让别人代理你做,别人总要会这个东西吧)

public interface IClassMethod {
    void playing(String something);

    void goHome(String goHome);
}

再来个Person类,这个类就是我们的被代理类啦,实现了IClassMethod这个接口

public class Person implements IClassMethod {
  public Person() {
      System.out.println("init person");
  }

  @Override
  public void playing(String something) {
      System.out.println(something);
  }

  @Override
  public void goHome(String goHome) {
      System.out.println(goHome);
  }
}

这时候有了被代理类,那么就来一个代理类PersonProxy,它需要有被代理类的实例对象,不然怎么知道要代理谁呢,当然也要实现了IClassMethod这个接口啦,不然怎么代替被代理的类做事呢:

public class PersonProxy implements IClassMethod {
    private Person mPerson;

    public PersonProxy(Person person) {
        mPerson = person;
    }

    @Override
    public void playing(String something) {
        mPerson.playing(something);
    }

    @Override
    public void goHome(String goHome) {
        mPerson.goHome(goHome);
    }
}

运行一下:

public class Test {
    public static void main(String[] args) {
        PersonProxy proxy=new PersonProxy(new Person());
        proxy.goHome("我回家了");
        proxy.playing("我在玩");
    }
}
静态代理

这样一整个静态代理就完成了,重新理一下静态代理:需要一个代理类(PersonProxy),一个被代理类(Person),还有一个两个都要实现的接口(IClassMethod),看PersonProxy代码就知道,其实就是在代理类(PersonProxy)里面使用Person来做操作,但是真正用的却是PersonProxy的方法。
        使用静态代理的话,也能实现普通的需求,但是如果有很多个被代理类呢,那不也要很多个代理类了么,那多麻烦,这时候就需要动态代理出场了。

动态代理
        Java中有两种实现动态代理方式:一种是使用jdk的反射机制,一种是使用cglib。我们这就介绍下使用反射这种。
        动态代理只能对接口代理,其中有两个很重要的东西,一个就是Proxy类和InvocationHandler接口,我们逐一介绍,Proxy就是Java提供生成代理类的类,里面有个newProxyInstance方法生成代理类,这方法有三个参数:

public static Object newProxyInstance(ClassLoader loader,
                                          Class<?>[] interfaces,
                                          InvocationHandler h)

第一个参数:ClassLoader类加载器
第二个参数:接口类
第三个参数:重要的InvocationHandler
前两个没啥好说的,最后一个才是重点,这个InvocationHandler里面就是一个方法

public Object invoke(Object proxy, Method method, Object[] args)
        throws Throwable;

这方法主要是用来调用代理类的方法的,第一个参数就是被代理类,第二个参数就是被代理类调用的方法,第三个就是方法的参数。
创建一个MyInvocationHandler里面做一些自己的操作:

public class MyInvocationHandler implements InvocationHandler {
    private Person mPerson;

    public MyInvocationHandler(Person person) {
        mPerson = person;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        for (int i = 0; i < args.length; i++) {
            if (method.getName().equals("playing"))
                args[i] = "我没在玩游戏";
        }
        return method.invoke(mPerson, args);
    }
}

然后再使用Proxy

public class Test {
    public static void main(String[] args) {
        IClassMethod personProxy = (IClassMethod) Proxy.newProxyInstance(Person.class.getClassLoader(),
                Person.class.getInterfaces(),
                new MyInvocationHandler(new Person()));
        personProxy.goHome("我回家了");
        personProxy.playing("我在玩游戏");
    }
}

可以看到,其实跟静态代理长的差不多,只不过这个代理类是jdk通过反射来生成的,这样只要是实现相同接口的类,都能使用动态代理,返回一个代理类。
看一下这个动态代理运行结果:

动态代理
        细心的大佬可能发现了,明明我在代理类传进去的是我在玩游戏,为何打印出来的却是我没在玩游戏,这就是在MyInvocationHandler这个类里面做了操作了:
InvocationHandler
所以最后结果就成了我没在玩游戏

总结

        静态代理:代理类和被代理类都是实现相同的接口,代理类持有被代理类实例,然后代理类来进行操作。

        动态代理:只能代理接口,使用jdk的反射机制自动创建代理类,并且自己实现InvocationHandler接口,在里面做一些自己的操作

        主要用途:当不想向外暴露类的内部实现或者想要扩展下类功能就可以使用代理方式。

相关文章

  • 设计模式之代理模式

    设计模式之代理模式 10分钟看懂动态代理设计模式(升级篇)-对这篇动态代理模式的思路整理 仿JDK实现动态代理逻辑...

  • 代理模式

    设计模式之代理模式 什么是代理模式? 指的事代理对象为其他对象提供代理以控制对被...

  • Java设计模式之代理模式

    Java设计模式之代理模式 代理模式 静态代理 动态代理 为什么需要代理 通过代理,我们能够不用知道委托人是谁,而...

  • Java代理模式之JDK动态代理

    了解什么是动态代理模式,可参考Java设计模式之代理模式 简介 JDK动态代理是java.lang.reflect...

  • 设计模式之代理模式2

    设计模式之代理模式运用 代理(Proxy)是一种设计模式,提供了对目标对象另外的访问方式;即通过代理对象访问目标对...

  • 设计模式之代理模式

    设计模式之代理模式 简介 代理模式是结构型设计模式。 当无法或不想直接访问某个对象或访问某个对象存在困难时可以通过...

  • 设计模式之代理模式

    title: 设计模式之代理模式date: 2018-08-15 20:25:42tags: 设计模式 笔记 Ja...

  • java设计模式之代理模式(静态代理)

      今天给大家分享的是java设计模式之代理模式中的静态代理模式,动态代理模式将在后面文章中给出。如有不足,敬请指...

  • Android 代理模式

    Android 设计模式系列文章 Android 23种设计模式 前言 代理模式可能是我们平时开发中最常见的模式之...

  • 设计模式之代理模式

    设计模式之代理模式 1.代理模式的定义 为其他对象提供一种代理以控制对这个对象的访问. 2.代理模式的使用场景 当...

网友评论

      本文标题:设计模式之代理模式

      本文链接:https://www.haomeiwen.com/subject/itpuyftx.html