代理模式

作者: Code猎人 | 来源:发表于2018-04-11 14:53 被阅读71次

前言

代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务

1、静态代理

静态代理通常用于对原有业务逻辑的扩充。比如持有二方包的某个类,并调用了其中的某些方法。然后出于某种原因,比如记录日志、打印方法执行时间,但是又不好将这些逻辑写入二方包的方法里。所以可以创建一个代理类实现和二方方法相同的方法,通过让代理类持有真实对象,然后在原代码中调用代理类方法,来达到添加我们需要业务逻辑的目的。

这其实也就是代理模式的一种实现,通过对真实对象的封装,来实现扩展性。

一个典型的代理模式通常有三个角色,这里称之为代理三要素

首先定义接口

public interface Action {
public void doSomething();
}

真实对象

public class RealObject implements Action{
public void doSomething() {
    System.out.println("do something");
}
}

代理对象

public class Proxy implements Action {
private Action realObject;

public Proxy(Action realObject) {
    this.realObject = realObject;
}
public void doSomething() {
    System.out.println("proxy do");
    realObject.doSomething();
}
}

运行代码

  Proxy proxy = new Proxy(new RealObject());
  proxy.doSomething();

这种代理模式也最为简单,就是通过proxy持有realObject的引用,并进行一层封装。

静态代理的优点和缺点

先看看代理模式的优点: 扩展原功能,不侵入原代码。

再看看这种代理模式的缺点:

假如有这样一个需求,有十个不同的RealObject,同时我们要去代理的方法是不同的,比要代理方法:doSomething、doAnotherThing、doTwoAnotherThing,添加代理前,原代码可能是这样的:

 realObject.doSomething();
 realObject1.doAnotherThing();
 realObject2.doTwoAnother();

2、Java动态代理

在静态代理中可以看到Proxy这个类做的工作无非就是在RealSubject的工作之前或之后插入其他的业务代码,如果每次都手动去实现Proxy类会比较繁琐,Java中引入了第三个类InvocationHandler,用来统一映射Proxy方法调用到RealSubject上。通过newProxyInstance可以帮助我们动态生成Proxy类实例。

接着看一下核心类和方法

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

返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序InvocationHandler

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

对于InvocationHandler,我们需要实现invoke方法,invoke方法根据代理类传递给自己的method参数来区分是什么方法

还是以上面栗子来做示范,Fly接口和Run接口不变,需要添加InvocationHandler的实现:

public class ProxyHandler implements InvocationHandler{

private RealObject mRealObject;

public ProxyHandler(RealObject realobject){
    mRealObject = realobject;
}


public Object invoke(Object proxy, Method method, Object[] args)
        throws Throwable {
    System.out.println("invoke" + method.getName());
    return method.invoke(mRealObject, args);
}

}

生成代理对象

public static void main(String[] args) {

    RealObject realobject = new RealObject();
    ClassLoader classLoader = realobject.getClass().getClassLoader();
    
    Class[] interfaces = realobject.getClass().getInterfaces();
    
    ProxyHandler proxyHandler = new ProxyHandler(realobject);
    
    ProxyUtils.generateClassFile(realobject.getClass(), "AnimalProxy");
    
    Object newProxyInstance = Proxy.newProxyInstance(classLoader, interfaces, proxyHandler);
    Action action = (Action)newProxyInstance;
    action.doSomething;
}

可以看出来核心代码就是
Proxy.newProxyInstance(classLoader, interfaces, proxyHandler);
我们分别来讲解下这三个参数分别是什么作用

  • classLoader:类加载器,我们手动写的都是java文件,需要编译成class文件,这个是遵循JVM规范的二进制文件,然后通过classLoader将class文件加载进内存,生成我们需要的class对象,这个class对象通过反射就可以拿到类的所有信息。在这边的作用其实就是将Java动态生成的class文件进行加载得到动态代理的class对象,以便后面其他操作。

  • interfaces:这个就是接口,可以看出无论代理或者RealSubject都是实现同样的接口,Java替我们动态生成的class文件中的方法其实就是接口中的方法。这个其实也是Java动态代理的缺点,即使RealSubject中声明的方法,但是接口中没有声明该方法,那么在生成的代理中就没有,也就是动态生成的代理类中只有接口中的方法,这个后面看栗子就清楚了。

  • proxyHandler:就是InvocationHandler的实现类,集成管理Proxy方法的调用映射到RealSubject中,主要就是在invoke中方法实现。在我们这个例子就是实现将Proxy方法调用映射到RealObject对应的方法上。

总结

动态代理和静态代理最大的不同就是Java SDK替我们动态生成了代理类代码,代理方法的调用最后都通过InvocationHandler映射到具体的实现类中。动态代理在Android中应用也是很多的,在下一篇里面会介绍一下 Android 反射注解和动态代理的综合使用


点赞加关注是给我最大的鼓励!

相关文章

  • 设计模式

    单例模式 模板方法模式 工厂模式 代理模式 静态代理 JDK动态代理

  • 设计模式

    单例模式 代理模式 静态代理 jdk动态代理 cglib动态代理 工厂模式 适配器模式 建造者模式 观察者模式

  • kube-proxy的3种模式

    userspace代理模式 iptables代理模式 IPVS代理模式 https://kubernetes.io...

  • 第4章 结构型模式-代理模式

    一、代理模式简介 二、代理模式3个角色 三、代理模式的优点 四、代理模式的实例(游戏代练)

  • 理解代理模式

    原创博客地址 简介 代理模式,也叫做委托模式,分为:静态代理动态代理 代理模式也是平时比较常用的设计模式之一,代理...

  • 结构型 代理模式(文末有项目连接)

    1:什么是代理模式 2:没用代理模式时的实例 3:使用代理模式将其解耦(静态代理) 3:使用代理模式将其解耦(动态...

  • 设计模式-动态代理模式

    之前介绍了代理模式,大家也都了解了代理模式,不过之前介绍的代理模式是静态代理,静态代理什么意思?静态代理指的是代理...

  • 代理模式

    一、什么是代理模式 代理模式(Proxy pattern):代理模式又叫委托模式,是为某个对象提供一个代理对象,并...

  • 设计模式之代理模式(Proxy模式)

    代理模式的引入 代理模式的实例程序 代理模式的分析 代理模式的引入 Proxy是代理人的意思,指的是代替别人进行工...

  • Java设计模式之代理模式

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

网友评论

    本文标题:代理模式

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