繼上一篇博客設(shè)計(jì)模式之代理模式學(xué)習(xí)之后http://blog.csdn.net/u014427391/article/details/75115928,本博客介紹JDK動(dòng)態(tài)代理的實(shí)現(xiàn)原理,學(xué)習(xí)一下JDK動(dòng)態(tài)代理的源碼。
Proxy類。該類即為動(dòng)態(tài)代理類,可以使用反編譯工具查看jdk里源碼。JDK動(dòng)態(tài)代理實(shí)現(xiàn)主要由Proxy類的newProxyInstance()方法實(shí)現(xiàn)。實(shí)現(xiàn)起來(lái)很容易,但是學(xué)習(xí)都要學(xué)習(xí)原理,所以本博客主要介紹jdk動(dòng)態(tài)代理實(shí)現(xiàn)的源碼。

newProxyInstance()方法用于根據(jù)傳入的接口類型interfaces返回一個(gè)動(dòng)態(tài)創(chuàng)建的代理類的實(shí)例,方法中第一個(gè)參數(shù)loader表示代理類的類加載器,第二個(gè)參數(shù)interfaces表示被代理類實(shí)現(xiàn)的接口列表,第三個(gè)參數(shù)h表示所指派的調(diào)用處理程序類。

首先寫個(gè)例子實(shí)現(xiàn)jdk動(dòng)態(tài)代理
主題接口類:

public interface IHello {    public void sayHello();
}

被代理的類:

public class Hello implements IHello{    public void sayHello() {
        System.out.println("hello!");
    }
}

JDK動(dòng)態(tài)代理InvocationHandler類

import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;public class MyInvocationHandler implements InvocationHandler {    private Object target;//委托類
    public MyInvocationHandler(Object target){        this.target=target;
    }

    @Override    public Object invoke(Object o, Method method, Object[] args) throws Throwable {        /**代理環(huán)繞**/
        //執(zhí)行實(shí)際的方法
        Object invoke = method.invoke(target, args);        return invoke;
    }
}

寫個(gè)類模擬字節(jié)碼文件生成:

import java.lang.reflect.Proxy;/**
 * Created by Nicky on 2017/7/20 0020.
 */public class Test {    public static void main(String[] args){
        System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
        IHello  ihello = (IHello) Proxy.newProxyInstance(IHello.class.getClassLoader(),  //加載接口的類加載器
                new Class[]{IHello.class},      //一組接口
                new MyInvocationHandler(new Hello())); //自定義的InvocationHandler
        ihello.sayHello();
    }
}

實(shí)現(xiàn)jdk動(dòng)態(tài)代理是很容易的,不過(guò)現(xiàn)在介紹一下jdk源碼,理解一下原理實(shí)現(xiàn)

下面看一下Proxy類里的newProxyInstance方法

 @CallerSensitive
    public static Object newProxyInstance(ClassLoader loader,
                                          Class<?>[] interfaces,
                                          InvocationHandler h)
        throws IllegalArgumentException    {
        Objects.requireNonNull(h);        //對(duì)象的拷貝
        final Class<?>[] intfs = interfaces.clone();        /*
         *  權(quán)限安全檢查
         */
        final SecurityManager sm = System.getSecurityManager();        if (sm != null) {
            checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
        }        /*
         * Look up or generate the designated proxy class.
         * (查找或生產(chǎn)指定的代理類。)
         */
        Class<?> cl = getProxyClass0(loader, intfs);        /*
         * Invoke its constructor with the designated invocation handler.
         * (使用指定的調(diào)用處理程序調(diào)用它的構(gòu)造函數(shù)。)
         */
        try {            if (sm != null) {
                checkNewProxyPermission(Reflection.getCallerClass(), cl);
            }            //獲取代理類的構(gòu)造函數(shù)
            final Constructor<?> cons = cl.getConstructor(constructorParams);            final InvocationHandler ih = h;            
            /*
             *  onstructor、Filed、Method都繼承自java.lang.reflect.AccessibleObject,
             *  訪問(wèn)非public的方法或者字段都會(huì)產(chǎn)生IllegalAccessException異常
             */
            if (!Modifier.isPublic(cl.getModifiers())) {
                AccessController.doPrivileged(new PrivilegedAction<Void>() {                    public Void run() {
                        cons.setAccessible(true);//setAccessible()為true可以繞過(guò)默認(rèn)的權(quán)限檢查
                        return null;
                    }
                });
            }            //根據(jù)代理類的構(gòu)造函數(shù)來(lái)創(chuàng)建代理對(duì)象
            return cons.newInstance(new Object[]{h});
        } catch (IllegalAccessException|InstantiationException e) {            throw new InternalError(e.toString(), e);
        } catch (InvocationTargetException e) {
            Throwable t = e.getCause();            if (t instanceof RuntimeException) {                throw (RuntimeException) t;
            } else {                throw new InternalError(t.toString(), t);
            }
        } catch (NoSuchMethodException e) {            throw new InternalError(e.toString(), e);
        }
    }

從newProxyInstance方法可以看出,生產(chǎn)代理類是由getProxyClass0獲取或者生成的。下面看一下getProxyClass0方法,從方法可以看出如果緩存中有代理類就直接返回代理的副本,否就使用ProxyClassFactory創(chuàng)建代理類。

 /**
     * Generate a proxy class.  Must call the checkProxyAccess method
     * to perform permission checks before calling this.
     */
    private static Class<?> getProxyClass0(ClassLoader loader,
                                           Class<?>... interfaces) {        //接口列表數(shù)目不能超過(guò)65535,因?yàn)樵赾lass文件中,這些個(gè)數(shù)都是用4位16進(jìn)制表示的,所以最大值是2的16次方-1  
        if (interfaces.length > 65535) {            throw new IllegalArgumentException("interface limit exceeded");
        }        // If the proxy class defined by the given loader implementing
        // the given interfaces exists, this will simply return the cached copy;
        // otherwise, it will create the proxy class via the ProxyClassFactory
        //如果緩存中有代理類就直接返回代理的副本,否就使用ProxyClassFactory創(chuàng)建代理類
        return proxyClassCache.get(loader, interfaces);
    }

proxyClassCache是一個(gè)WeakCache類型的緩存,它的構(gòu)造函數(shù)有兩個(gè)參數(shù),其中一個(gè)就是用于生成代理類的ProxyClassFactory,看一下proxyClassCache.get方法的代碼:

public V get(K key, P parameter) {
        Objects.requireNonNull(parameter);        //清理持有弱引用的WeakHashMap這種數(shù)據(jù)結(jié)構(gòu)
        expungeStaleEntries();        //從隊(duì)列中獲取cacheKey
        Object cacheKey = CacheKey.valueOf(key, refQueue);        // lazily install the 2nd level valuesMap for the particular cacheKey
        //懶加載的方式封裝第二層valueMap,ConcurrentMap是一種線程安全的Map
        ConcurrentMap<Object, Supplier<V>> valuesMap = map.get(cacheKey);        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
        // subKey from valuesMap
        Object subKey = Objects.requireNonNull(subKeyFactory.apply(key, parameter));
        Supplier<V> supplier = valuesMap.get(subKey);
        Factory factory = null;        while (true) {            if (supplier != null) {                // supplier might be a Factory or a CacheValue<V> instance
                //核心代碼,從supplier或者value,可能返回工廠實(shí)例或者Cache實(shí)例,返回實(shí)現(xiàn)InvokeHandler的類并包含了所需要的信息。
                V value = supplier.get();                if (value != null) {                    return value;
                }
            }            // else no supplier in cache
            // or a supplier that returned null (could be a cleared CacheValue
            // or a Factory that wasn't successful in installing the CacheValue)

            // lazily construct a Factory
            //懶加載方式構(gòu)建工廠實(shí)例
            if (factory == null) {
                factory = new Factory(key, parameter, subKey, valuesMap);
            }            /**填充supplier**/
            if (supplier == null) {
                supplier = valuesMap.putIfAbsent(subKey, factory);                if (supplier == null) {                    // successfully installed Factory
                    supplier = factory;
                }                // else retry with winning supplier
            } else {                if (valuesMap.replace(subKey, supplier, factory)) {                    // successfully replaced
                    // cleared CacheEntry / unsuccessful Factory
                    // with our Factory
                    supplier = factory;
                } else {                    // retry with current supplier
                    supplier = valuesMap.get(subKey);
                }
            }
        }
    }

若緩存中找不到代理類,就使用ProxyClassFactory生產(chǎn)代理類,看一下ProxyClassFactory類的代碼:

 /**
     * A factory function that generates, defines and returns the proxy class given
     * the ClassLoader and array of interfaces.
     */
    private static final class ProxyClassFactory        implements BiFunction<ClassLoader, Class<?>[], Class<?>>
    {        // prefix for all proxy class names(統(tǒng)一所以代理類的前綴名都以$Proxy開(kāi)始)
        private static final String proxyClassNamePrefix = "$Proxy";        // next number to use for generation of unique proxy class names
        //給每個(gè)代理類名加個(gè)唯一的編號(hào),如$Proxy0,$Proxy1等等
        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;                //通過(guò)類名加載每一個(gè)接口運(yùn)行時(shí)的信息
                try {
                    interfaceClass = Class.forName(intf.getName(), false, loader);
                } catch (ClassNotFoundException e) {
                }                //驗(yàn)證使用classLoad加載的類與傳入的類是否相同
                if (interfaceClass != intf) {                    throw new IllegalArgumentException(
                        intf + " is not visible from class loader");
                }                /*
                 * Verify that the Class object actually represents an
                 * interface.
                 * 驗(yàn)證傳入的是否為接口類型,因?yàn)閖dk動(dòng)態(tài)代理只支持接口類型
                 */
                if (!interfaceClass.isInterface()) {                    throw new IllegalArgumentException(
                        interfaceClass.getName() + " is not an interface");
                }                /*
                 * Verify that this interface is not a duplicate.
                 * 驗(yàn)證接口是否重復(fù)
                 */
                if (interfaceSet.put(interfaceClass, Boolean.TRUE) != null) {                    throw new IllegalArgumentException(                        "repeated interface: " + interfaceClass.getName());
                }
            }            String proxyPkg = null;     // package to define proxy class in
            int accessFlags = Modifier.PUBLIC | Modifier.FINAL;            /*
  http://www.cnblogs.com/mzq123/p/7215966.html