• JDK7动态代理源码分析


    IObject proxy = (IObject) Proxy.newProxyInstance(IObject.class.getClassLoader(),                                   
                                 new Class[]{IObject.class},                   new DynamicProxyHandler(real) );

    使用Proxy类的静态方法newProxyInstance创建一个动态代理类

    查看API文档:

    public static Object newProxyInstance(ClassLoader loader,
                                          Class<?>[] interfaces,
                                          InvocationHandler h)
                                   throws IllegalArgumentException
    loader - 定义代理类的类加载器 
    interfaces - 代理类要实现的接口列表 
    h - 指派方法调用的调用处理程序 

    1、JDK动态代理要求,被代理的必须是个接口,单纯的类则不行,即interfaces必须是接口

    2、JDK代理所生成的代理类都会继承Proxy类,同时代理类会实现所有传入的接口列表(即interfaces),因此可以强制类型转换成接口类型。

    3、如果非要代理一个没有实现接口的类,同时该类的方法与其他接口的方法相同,则需要利用反射实现

    //利用反射获取你想代理的类的方法
    Method myMethod = targetClass.getClass().getDeclaredMethod(method.getName(), method.getParameterTypes());
        myMethod.setAccessible(true);

    4、newProxyInstance方法相当于getProxyClass方法

    Proxy.getProxyClass(loader, interfaces).
             getConstructor(new Class[] { InvocationHandler.class }).
             newInstance(new Object[] { handler });

    源码分析:

    @CallerSensitive
        public static Object newProxyInstance(ClassLoader loader,
                                              Class<?>[] interfaces,
                                              InvocationHandler h)
            throws IllegalArgumentException
        {
            if (h == null) {
                throw new NullPointerException();
            }
    
            //拷贝一份所有接口的数组
            final Class<?>[] intfs = interfaces.clone();
            /**
             * 安全管理器主要用来防止恶意攻击,根据java安全策略文件觉得将哪组权限授予类
             * 每个java应用都有自己的安全管理器,
             * 如果要使用,可以在jvm启动时设定-Djava.security.manager选项,还可以同时指定安全策略文件。
             * 如果在应用中启用了Java安全管理器,却没有指定安全策略文件,那么Java安全管理器将使用默认的安全策略,它们是由位于目录$JAVA_HOME/jre /lib/security中的java.policy定义的。 
             */
            final SecurityManager sm = System.getSecurityManager();
            if (sm != null) {
                checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
            }
            /**
             * 调用getProxyClass0方法拿到代理类的Class对象
             */
            Class<?> cl = getProxyClass0(loader, intfs);

    调用getProxyClass0:

     /** 代理类的缓存 */
    private static final WeakCache<ClassLoader, Class<?>[], Class<?>>
            proxyClassCache = new WeakCache<>(new KeyFactory(), new ProxyClassFactory());

    private
    static Class<?> getProxyClass0(ClassLoader loader, Class<?>... interfaces) { //如果目标类的接口数大于65535 if (interfaces.length > 65535) { throw new IllegalArgumentException("interface limit exceeded"); } // 如果代理类已经在缓存中,则直接取出,否则用ProxyClassFactory创建新代理类 return proxyClassCache.get(loader, interfaces); }

    调用WeakCache的get方法:

    private final ReferenceQueue<K> refQueue
            = new ReferenceQueue<>();
    /**
    * K 表示key * P 表示parameters * V 表示value */ public V get(K key, P parameter) { //NullObject判断方法 Objects.requireNonNull(parameter); //清理持有弱引用的WeakHashMap这种数据结构 expungeStaleEntries(); //从队列中获取cacheKey Object cacheKey = CacheKey.valueOf(key, refQueue);

    调用CacheKey的valueOf

    java.lang.ref.Reference
    Reference(T referent, ReferenceQueue<? super T> queue) {
            this.referent = referent;
            this.queue = (queue == null) ? ReferenceQueue.NULL : queue;
        }

    private
    static final class CacheKey<K> extends WeakReference<K> { // a replacement for null keys private static final Object NULL_KEY = new Object(); static <K> Object valueOf(K key, ReferenceQueue<K> refQueue) { return key == null ? NULL_KEY : new CacheKey<>(key, refQueue); } private final int hash; private CacheKey(K key, ReferenceQueue<K> refQueue) { super(key, refQueue);
           //返回给定对象的哈希码,
                //该代码与默认的方法 hashCode() 返回的代码一样,无论给定对象的类是否重写 hashCode()。null 引用的哈希码为 0。
    this.hash = System.identityHashCode(key); }

    ReferenceQueue的源码先暂时不分析,回到WeakCache中get方法

    //利用懒加载的方式获取cacheKey对应的Supplier
            ConcurrentMap<Object, Supplier<V>> valuesMap = map.get(cacheKey);
            //如果map中不存在cache键值对,则把cacheKey对应的键值对放进map
            if (valuesMap == null) {
                ConcurrentMap<Object, Supplier<V>> oldValuesMap
                    = map.putIfAbsent(cacheKey,
                                      valuesMap = new ConcurrentHashMap<>());
                if (oldValuesMap != null) {
                    valuesMap = oldValuesMap;
                }
            }
    
            // create subKey and retrieve the possible Supplier<V> stored by that
            // subKeyFactory.apply调用Proxy中KeyFactory静态类的apply方法
            Object subKey = Objects.requireNonNull(subKeyFactory.apply(key, parameter));
    
    subKeyFactory.apply调用Proxy中KeyFactory静态类的apply方法
     private static final class KeyFactory
            implements BiFunction<ClassLoader, Class<?>[], Object>
        {
            @Override
            public Object apply(ClassLoader classLoader, Class<?>[] interfaces) {
                switch (interfaces.length) {
                    case 1: return new Key1(interfaces[0]); // the most frequent
                    case 2: return new Key2(interfaces[0], interfaces[1]);
                    case 0: return key0;
                    default: return new KeyX(interfaces);
                }
            }
        }

    Key1、Key2、KeyX都是Proxy的内部类

    /*
         * Key1 and Key2 都是用来给实现了1个或者2个接口的代理类使用
         */
        private static final class Key1 extends WeakReference<Class<?>> {
            private final int hash;
    
            Key1(Class<?> intf) {
                super(intf);
                this.hash = intf.hashCode();
            }
    
            @Override
            public int hashCode() {
                return hash;
            }
    
            @Override
            public boolean equals(Object obj) {
                Class<?> intf;
                return this == obj ||
                       obj != null &&
                       obj.getClass() == Key1.class &&
                       (intf = get()) != null &&
                       intf == ((Key1) obj).get();
            }
        }
    
        private static final class Key2 extends WeakReference<Class<?>> {
            private final int hash;
            private final WeakReference<Class<?>> ref2;
    
            Key2(Class<?> intf1, Class<?> intf2) {
                super(intf1);
                hash = 31 * intf1.hashCode() + intf2.hashCode();
                ref2 = new WeakReference<Class<?>>(intf2);
            }
    
            @Override
            public int hashCode() {
                return hash;
            }
    
            @Override
            public boolean equals(Object obj) {
                Class<?> intf1, intf2;
                return this == obj ||
                       obj != null &&
                       obj.getClass() == Key2.class &&
                       (intf1 = get()) != null &&
                       intf1 == ((Key2) obj).get() &&
                       (intf2 = ref2.get()) != null &&
                       intf2 == ((Key2) obj).ref2.get();
            }
        }
    
        /*
         * 用来给实现了3个或3个以上接口的代理类使用
         */
        private static final class KeyX {
            private final int hash;
            private final WeakReference<Class<?>>[] refs;
    
            KeyX(Class<?>[] interfaces) {
                hash = Arrays.hashCode(interfaces);
                refs = new WeakReference[interfaces.length];
                for (int i = 0; i < interfaces.length; i++) {
                    refs[i] = new WeakReference(interfaces[i]);
                }
            }
    
            @Override
            public int hashCode() {
                return hash;
            }
    
            @Override
            public boolean equals(Object obj) {
                return this == obj ||
                       obj != null &&
                       obj.getClass() == KeyX.class &&
                       equals(refs, ((KeyX) obj).refs);
            }
    
            private static boolean equals(WeakReference<Class<?>>[] refs1,
                                          WeakReference<Class<?>>[] refs2) {
                if (refs1.length != refs2.length) {
                    return false;
                }
                for (int i = 0; i < refs1.length; i++) {
                    Class<?> intf = refs1[i].get();
                    if (intf == null || intf != refs2[i].get()) {
                        return false;
                    }
                }
                return true;
            }
        }

    回到get方法:

    //
            Supplier<V> supplier = valuesMap.get(subKey);
            Factory factory = null;
    
            while (true) {
                if (supplier != null) {
                    //调用Factory实现的get方法,返回实现InvokeHandler的类,并包含了所需要的信息
                    V value = supplier.get();
                    if (value != null) {
                        return value;
                    }
                }
    
                //懒加载构建工厂
                if (factory == null) {
                    /**
                     *创建一个工厂
                     key           classloader
                     parameter  interfaces接口
                     subkey     存储interfaces的对象
                     valuesMap     cacheKey键值对
                     */
                    factory = new Factory(key, parameter, subKey, valuesMap);
                }
    
                if (supplier == null) {
                    supplier = valuesMap.putIfAbsent(subKey, factory);
                    if (supplier == null) {
                        //填充supplier
                        supplier = factory;
                    }
                } else {
                    if (valuesMap.replace(subKey, supplier, factory)) {
                        supplier = factory;
                    } else {
                        supplier = valuesMap.get(subKey);
                    }
                }
            }

    调用Supplier子类Factory的get方法:

    @Override
            public synchronized V get() { 
                // 重新检查supplier
                Supplier<V> supplier = valuesMap.get(subKey);
                if (supplier != this) {
                    return null;
                }
    
                V value = null;
                try {
                    //调用Proxy类种ProxyFactoryClass的apply方法,apply才是真正创建代理类的方法
                    value = Objects.requireNonNull(valueFactory.apply(key, parameter));
                } finally {
                    if (value == null) { // remove us on failure
                        valuesMap.remove(subKey, this);
                    }
                }
                // the only path to reach here is with non-null value
                assert value != null;
    
                // wrap value with CacheValue (WeakReference)
                CacheValue<V> cacheValue = new CacheValue<>(value);
    
                // try replacing us with CacheValue (this should always succeed)
                if (valuesMap.replace(subKey, this, cacheValue)) {
                    // put also in reverseMap
                    reverseMap.put(cacheValue, Boolean.TRUE);
                } else {
                    throw new AssertionError("Should not reach here");
                }
    
                // successfully replaced us with new CacheValue -> return the value
                // wrapped by it
                return value;
            }

    调用ProxyFactoryClass的apply方法:

    private static final class ProxyClassFactory
            implements BiFunction<ClassLoader, Class<?>[], Class<?>>
        {
            //动态代理类的前缀
            private static final String proxyClassNamePrefix = "$Proxy";
    
            //最终动态代理类的名字一般都是$ProxyN (N=0,1,2,3,4,5,6,7,8)
            private static final AtomicLong nextUniqueNumber = new AtomicLong();
            //真正创建代理类的方法
            @Override
            public Class<?> apply(ClassLoader loader, Class<?>[] interfaces) {
    
                Map<Class<?>, Boolean> interfaceSet = new IdentityHashMap<>(interfaces.length);
                for (Class<?> intf : interfaces) {
                    /*
                     * Verify that the class loader resolves the name of this
                     * interface to the same Class object.
                     */
                    Class<?> interfaceClass = null;
                    try {
                        //加载每一个接口运行时的信息,返回接口对应的类对象
                        interfaceClass = Class.forName(intf.getName(), false, loader);
                    } catch (ClassNotFoundException e) {
                    }
                    //如果使你自己定义的ClassLoader加载的class与你传入的class不一样,则抛出异常
                    if (interfaceClass != intf) {
                        throw new IllegalArgumentException(
                            intf + " is not visible from class loader");
                    }
                    /*
                     * 判断Class对象是否是一个接口
                     */
                    if (!interfaceClass.isInterface()) {
                        throw new IllegalArgumentException(
                            interfaceClass.getName() + " is not an interface");
                    }
                    /*
                     * 验证接口是否重复
                     */
                    if (interfaceSet.put(interfaceClass, Boolean.TRUE) != null) {
                        throw new IllegalArgumentException(
                            "repeated interface: " + interfaceClass.getName());
                    }
                }
    
                String proxyPkg = null;     // package to define proxy class in
    
                /*
                 * 检查传入的接口里有没有不是public的接口,如果有,这些接口必须在一个包里
                 */
                for (Class<?> intf : interfaces) {
                    int flags = intf.getModifiers();
                    if (!Modifier.isPublic(flags)) {
                        String name = intf.getName();
                        int n = name.lastIndexOf('.');
                        String pkg = ((n == -1) ? "" : name.substring(0, n + 1));
                        if (proxyPkg == null) {
                            proxyPkg = pkg;
                        } else if (!pkg.equals(proxyPkg)) {
                            throw new IllegalArgumentException(
                                "non-public interfaces from different packages");
                        }
                    }
                }
    
                if (proxyPkg == null) {
                    //如果没有非公共的代理接口, 则使用com.sun.proxy package
                    proxyPkg = ReflectUtil.PROXY_PACKAGE + ".";
                }
    
                //为生成的代理类选择一个名字 com.sun.proxy $Proxy0
                long num = nextUniqueNumber.getAndIncrement();
                String proxyName = proxyPkg + proxyClassNamePrefix + num;
    
                //生成代理类字节码
                byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
                    proxyName, interfaces);
                try {
                    //根据代理类的字节码生成代理类的实例
                    return defineClass0(loader, proxyName,
                                        proxyClassFile, 0, proxyClassFile.length);
                } catch (ClassFormatError e) {
                    
                    throw new IllegalArgumentException(e.toString());
                }
            }
        }

    调用ProxyGenerator.generateProxyClass( proxyName, interfaces);生成接口对应的字节码

    public static byte[] generateProxyClass(final String name,
                            Class[] interfaces)
        {
        ProxyGenerator gen = new ProxyGenerator(name, interfaces);
    //生成字节码
    final byte[] classFile = gen.generateClassFile(); if (saveGeneratedFiles) { java.security.AccessController.doPrivileged( new java.security.PrivilegedAction() { public Object run() { try { FileOutputStream file = new FileOutputStream(dotToSlash(name) + ".class"); file.write(classFile); file.close(); return null; } catch (IOException e) { throw new InternalError( "I/O exception saving generated file: " + e); } } }); } return classFile; }

    调用Proxy.defineClass0本地方法把字节码生成代理类的实例

  • 相关阅读:
    HDU 1202 The calculation of GPA
    HDU 1201 18岁生日
    HDU 1200 To and Pro
    C语言实现的图的深度搜索与广度搜索程序
    深度优先搜索和广度优先搜索的深入讨论
    Linux sftp 安全文件传输命令
    看白鹿原有感
    中国人民抗日战争暨世界反法西斯战争胜利70周年(20150903)
    高一的我曾对自己说"要放慢脚步去生活"!?
    网络营销(续)
  • 原文地址:https://www.cnblogs.com/wangwanchao/p/6239113.html
Copyright © 2020-2023  润新知