动态代理原理解析

之前有一篇设计模式的文章说过了代理模式。这一篇是对之前的补充跟深入。

1 为什么需要学习动态代理

1.动态代理能够增加程序灵活度,如加入 方法执行前后判断

2 完美解决解耦问题动态代理可以将调用层与实现层分离,如Retorfit网络请求

3 动态代理不需要接口的实现类,如 适用于 IPC进程通信,将方法调用转成其他逻辑1.动态代理不需要接口的实现类,如 适用于 IPC进程通信,将方法调用转成其他逻辑

4 动态代理可以解决 程序执行流程,如今天讲的事件转到activity执行

动态代理含义

1定义:给目标对象提供一个代理对象,并由代理对象控制对目标对象的引用

2目的: (1) 通过引入代理对象的方式来间接访问目标对象,防止直接访问目标对象给系统带来的不必要复杂性

为什么会有动态代理

传统面向对象思想中,如果想要实现功能复用,要么继承、要么引用,无论哪种方式,对代码都有一定的侵入性,耦合无可避免

侵入性含义:如果你想要用它增强你程序的功能,你必须改动你的程序代码,那它就具有侵入性。如果只有一点两点需要增强还好说,如果大量的功能点需要被增强,工作量就会很大,代码也不太优雅。想象一下,如果你对外公开了一系列的接口,现在领导说了,接口要加权限控制。在哪加?最笨的当然就是写个程序验证的逻辑,然后每个接口都拿来调用一遍。这也正是面向对象思想的短板,在要为程序新增一些通用功能时,只能通过耦合的方式才能进行。AOP正是为此而生,AOP旨在通过一种无耦合的方式来为程序带来增强。而动态代理就是AOP实现方式中的一种.

动态代理应用场景

1. 权限 集中 申请
2. 日志集中打印
3. 底层屏蔽具体网络请求, Retorfit 网络请求
4. RPC 即远程过程调用
5. 需要对较难修改的类方法进行功能增加

Android中动态代理有哪几种实现方式

1. Java   Proxy (接口实现
2. AspectJ
3. Cglib ( 只能 java 用, Android 用不了 )

2 Proxy动态代理如何实现代理

核心原理:编译时 ,代理对象的class并不存在,当需要调用Proxy.newProxyInstance时,会构建一个Proxy0class字节码,并且加载到内存。

byte[] bytes = ProxyGenerator.generateProxyClass("DavidHelloImpl", new Class[]{HelloInterface.class});

3 ProxyGenerator如何生成一个Class文件

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

可以看到这里生成了一个${name}.class ,那么name是哪里传来的。我们继续跟踪Proxy类中的

defineProxyClass方法。

从这里标记的可以看到name的命名。是不是很熟悉,$proxy。

这里我们看下手动调用ProxyGenerator,生成class 文件输入到文本看下class内部。

byte[] bytes = ProxyGenerator.generateProxyClass("HelloImpl", new Class[]{HelloInterface.class});
File file = new File("C:\\Users\\Administrator\\Downloads\\Proxy\\proxy\\src\\main\\java\\com\\maniu\\proxy\\HelloImpl.class");
FileOutputStream outputStream = new FileOutputStream(file);
outputStream.write(bytes);
outputStream.flush();
outputStream.close();

生成看到内部实现接口中的方式,是调用h.invoke()方法。

从上可知,h就是InvocationHandler

HelloInterface helloInterface= (HelloInterface) Proxy.newProxyInstance(hello.getClass()
                .getClassLoader(),
        hello.getClass().getInterfaces(),
        new ProxyHandler(hello));
static class ProxyHandler implements InvocationHandler {
//        代理对象   张三
        private Object object;
        public ProxyHandler(Object object){
            this.object = object;
        }
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            method.invoke(object, args);
            return null;
        }
    }

所以在调用调用代理类内部的方法后,会执行ProxyHandler 内部的invoke()方法。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值