Android-动态代理之Java Proxy

241 阅读2分钟

src=http___5b0988e595225.cdn.sohucs.com_images_20171212_e0eb86a738bc4d929206be96908a5219.jpeg&refer=http___5b0988e595225.cdn.sohucs.jpeg

动态代理的优点:
  1. 动态代理能够增加程序的灵活度(eg:加入方法执行前后的判断)
  2. 完美解决耦合问题,动态代理可以将调用层和实现层分离(eg:retorfit网路请求)
  3. 动态代理不需要接口的实现类(eg:ipc进程通讯,将方法调用转成其他逻辑)
  4. 动态代理可以解决程序执行流程的问题。
动态代理的含义
定义:给目标对象提供一个代理对象,并由代理对象控制对目标对象的引用。
作用:通过引入代理对象的方式来间接访问目标对象,防止直接访问目标对象给对象系统带来不必要复杂性。
为什么会有动态代理
传统面向对象中,如果想要实现功能的复用,要么继承,要么引用,但是无论哪种方式,
对代码都有一定的浸入性,耦合无可避免。
浸入性含义:
如果你想用它增强你程序的功能,你必须改动现有程序的代码,那它就具有侵入性。如果只是一点两点需要增强还好,
如果大量的功能点需要被增强,工作量就会很大,代码也不太优雅。想象一下如果你对外公开的一系列的接口,
要添加一个权限控制,那样你就需要对每个接口都来校验一边。这就可以看出面向对象思想的短板,要为程序
新增一些通用功能,只能通过耦合的方式才能进行。AOP正式为了解决这个问题而生,AOP是通过一种无耦合的
方式来为程序带来增强。而动态代理就是AOP的一种实现方式
动态代理应用的场景
  1. 权限集中申请
  2. 日志集中打印
  3. 底层屏蔽具体网络请求(retorfit网络请求)
  4. RPC远程过程调用
  5. 需要对较难修改的类方法进行功能增强
Android中动态代理的实现方式
  1. Java Proxy(接口实现)
  2. AspectJ 备注:Cglib(只能java用,Android用不了)
Java Proxy代理的示例代码

首先需要有一个接口

public interface HelloInterface {
    void sayHello();
}

其次需要有一个实现类


public class HelloImpl implements HelloInterface{
    @Override
    public void sayHello() {
       System.out.println(">>>>>>>>sayHello<<<<<<<<<<<");
    }
}

最后调用的代码

public static void main(String[] args) {
    HelloImpl hello=new HelloImpl();
    HelloInterface helloInterface = (HelloInterface) Proxy.newProxyInstance(hello.getClass().getClassLoader(),
            hello.getClass().getInterfaces(), new ProxyHandler());
    helloInterface.sayHello();

}
static class ProxyHandler implements InvocationHandler{
    @Override
    public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
        System.out.println("arrom>>>>>>>>>>>>>>调用");
        return null;
    }
}

大致的调用过程如图:

image.png

源码分析:

//生成一个运行时对象
byte[] proxyClassFile = ProxyGenerator.generateProxyClass(proxyName, (Class[])interfaces.toArray(Proxy.EMPTY_CLASS_ARRAY), accessFlags);

ProxyGenerator能够在运行时生成一个对象,而且这个对象是实现了该接口。这个对象所属的类是一个全新的class。Class需要生成才能加载,而ProxyGenerator在运行时,是生成class字节码,并且加入内存。

sayhello的调用过程(动态代理的原理)

image.png