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本地方法把字节码生成代理类的实例

 

posted @ 2019-04-24 14:58  impwang  阅读(202)  评论(0编辑  收藏  举报