美文网首页
Proxy源码学习

Proxy源码学习

作者: tiancijiaren | 来源:发表于2017-07-12 09:48 被阅读0次

动态代理使用不在累述。InvocationHandler.invoke的第一个参数proxy值是newProxyInstance返回的动态代理类的实例,不是被代理的实例。
动态代理类Proxy是结合java底层实现的,通过纯粹的java代码实现比较困难。
需要java动态生成类的支持。

要创建一个可以代理任何接口的类:

1.必须要知道要被代理的接口列表;
2.要有一个可以加载这个代理类的ClassLoader;
3.为了能够在调用被代理实例接口时能够动态的添加需要的处理,需要一个接口回调,并在回调中采用反射的形式调用实际的实例方法。

实现过程:以下Proxy是实现动态代理的过程

public interface Subject{
public void rent();
public void hello(String str);
}
public class RealSubject implements Subject{
@Override
public void rent() {
System.out.println("I want to rent my house");
}
@Override
public void hello(String str) {
System.out.println("hello: " + str);
}
}
public class DynamicProxyHandler implements InvocationHandler {
// 被代理对象
private Object subject;
public DynamicProxy(Object subject) {
this.subject = subject;
}
@Override
public Object invoke(Object object, Method method, Object[] args) throws Throwable {
// 在代理真实对象前我们可以添加一些自己的操作
System.out.println("Method:" + method);
// 当代理对象调用真实对象的方法时,其会自动的跳转到代理对象关联的handler对象的invoke方法来进行调用
method.invoke(subject, args);
// 在代理真实对象后我们也可以添加一些自己的操作
System.out.println("after rent house");
return null;
}
}
public static void main(String[] args) {
Subject realSubject = new RealSubject();
InvocationHandler handler = new DynamicProxyHandler(realSubject);
Subject subject = (Subject)Proxy.newProxyInstance(handler.getClass().getClassLoader(), realSubject
.getClass().getInterfaces(), handler);
System.out.println(subject.getClass().getName());
subject.rent();
subject.hello("world");
}
subject.getClass().getName()打印的值是:$Proxy0


image.png

猜测大概的$Proxy0类如下(可以通过反射查看其中的一部分实际内容):

// 类的包名应该是和Proxy在同一个包下
public class Proxy0 implements Subject {
    private InvocationHandler handler;
    public Proxy0(InvocationHandler handler) {
        this.handler = handler;
    }

    public void rent() {
        Thread.currentThread().getStackTrace()[2].getMethodName();
        // 通过反射获取当前函数名称和参数列表,传给invoke
        Proxy.invoke(this, method, args);
    }

    public void hello(String str) {
        Proxy.invoke(this, method, args);
    }
}

InvocationHandler的实现可以多种多样,根据不同需求进行不同实现。

相关文章

  • Proxy源码学习

    动态代理使用不在累述。InvocationHandler.invoke的第一个参数proxy值是newProxyI...

  • 支持多线程的代理IP池

    python源码 使用示例: pool = Proxy() 构造代理池类 pool = Proxy(min_poo...

  • Istio Proxy【Envoy扩展】详解

    [TOC] Istio Proxy【Envoy扩展】详解 源码工程和基本介绍 istio proxy工程概要 is...

  • 3proxy--windows 二次开发

    github 源码链接 [3proxy] (https://github.com/z3APA3A/3proxy)但...

  • node-http-proxy 源码学习

    什么是代理? 下面给出一幅图说说我的简单理解: 如上图所示,代理服务器挡在了服务器的面前。对于用户来说,是不知道这...

  • 即用即弃型邮箱

    python源码 使用示例: email = Email() 构造邮箱类 email = Email(proxy=...

  • JDK Proxy 源码

    说到动态代理的受限于的接口的,这包括两个方面 非接口不能使用JDK动态代理 若一个类实现了接口(implement...

  • OkHttp源码解析 (三)——代理和路由

    一、前言 初看OkHttp源码,由于对Address、Route、Proxy、ProxySelector、Rout...

  • java随笔(十一)

    java动态代理源码分析,总结。java动态代理实现步骤: 通过阅读源码发现,动态生成代理对象$Proxy0,该对...

  • ECMAScript 6学习(六)

    defineProperty() 学习书籍《ECMAScript 6 入门 》 Proxy Proxy 用于修改某...

网友评论

      本文标题:Proxy源码学习

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