• Java--JDK动态代理核心源码解析


    1、首先我们了解一下JDK动态代理的使用方法:

        public static void main(String[] args) {
            /**
             * 创建一个Bean对象,该对象实现BeanInterFace接口
             */
            BeanInterFace bean = new Bean();
    
            /**
             * 创建一个MyProxy对象,该对象实现InvocationHandler接口,将bean注入到MyProxy中
             */
            InvocationHandler invocationHandler = new MyProxy(bean);
    
            /**
             * 调用JDK的Proxy类,使用newProxyInstance方法,直接生成Bean对象的代理对象
             * 注意:Classloader必须采用实际代理对象的ClassLoader,否则会出现反复调用的问题
             */
            BeanInterFace beanProxy = (BeanInterFace) Proxy.newProxyInstance(bean.getClass().getClassLoader(),
                    bean.getClass().getInterfaces(),invocationHandler);
    
            /**
             * 使用代理对象
             */
            System.out.println(beanProxy.getClass().getName());
            beanProxy.say();
        }

    2、我们看一下JDK源码,是如何实现动态代理的

    Proxy.newProxyInstance最终会调用Proxy.ProxyClassFactory.apply()方法生成代理Class

             //创建proxyname,通过package+ClassName+编号
            String proxyName = proxyPkg + proxyClassNamePrefix + num; /* * 这里生成了代理的Class,并编译返回二进制byte[]数组 */ byte[] proxyClassFile = ProxyGenerator.generateProxyClass( proxyName, interfaces, accessFlags); try {
    //这里加载了ProxyClass,这里的加载用的是系统appClassLoader,至今我还没明白怎么才能使用,JDK使用的native方法
    return defineClass0(loader, proxyName, proxyClassFile, 0, proxyClassFile.length); } catch (ClassFormatError e) { /* * A ClassFormatError here means that (barring bugs in the * proxy class generation code) there was some other * invalid aspect of the arguments supplied to the proxy * class creation (such as virtual machine limitations * exceeded). */ throw new IllegalArgumentException(e.toString()); }

    3、具体proxyClass是如何生成的

    大致就是:

    proxyClass有一个构造函数,该构造函数的参数为InvocationHandler接口,proxyClass实例化以后将InvocationHandler的引用储存在自己的属性中,然后proxyClass每个方法的触发都会触发InvocationHandler的invoke方法,通过反射调用真实对象的的方法。

  • 相关阅读:
    颠倒的价牌|2013年蓝桥杯A组题解析第四题-fishers
    振兴中华|2013年蓝桥杯A组题解析第三题-fishers
    排它平方数|2013年蓝桥杯A组题解析第二题-fishers
    L2-001:dijskstra + 多条最短路径 + 记录中间路径
    2018 蓝桥杯省赛 B 组模拟赛(五)
    差分数组|小a的轰炸游戏-牛客317E
    差分数组
    线性基
    transformer中自注意力和多头注意力的pytorch实现
    transformer中的位置嵌入pytorch代码
  • 原文地址:https://www.cnblogs.com/eoss/p/6136526.html
Copyright © 2020-2023  润新知