Java动态代理深入解析(4)

synchronized (cache) {
            /*
            * Note that we need not worry about reaping the cache for
            * entries with cleared weak references because if a proxy class
            * has been garbage collected, its class loader will have been
            * garbage collected as well, so the entire cache will be reaped
            * from the loaderToCache map.
            */
            do {
                Object value = cache.get(key);
                if (value instanceof Reference) {
                    proxyClass = (Class<?>) ((Reference) value).get();
                }
                if (proxyClass != null) {
                    // proxy class already generated: return it
                    return proxyClass;
                } else if (value == pendingGenerationMarker) {
                    // proxy class being generated: wait for it
                    try {
                        cache.wait();
                    } catch (InterruptedException e) {
                        /*
                        * The class generation that we are waiting for should
                        * take a small, bounded time, so we can safely ignore
                        * thread interrupts here.
                        */
                    }
                    continue;
                } else {
                    /*
                    * No proxy class for this list of interfaces has been
                    * generated or is being generated, so we will go and
                    * generate it now.  Mark it as pending generation.
                    */
                    cache.put(key, pendingGenerationMarker);
                    break;
                }
            } while (true);
        }
     //确认要生成的代理类所属的包,如果interfaces里所有接口都是public的,代理类所属包就是默认包;如果有interface不是public,那么所有不是public的interface必须在一个包里否则报错。
        try {
            String proxyPkg = null;    // package to define proxy class in

/*
            * Record the package of a non-public proxy interface so that the
            * proxy class will be defined in the same package.  Verify that
            * all non-public proxy interfaces are in the same package.
            */
            for (int i = 0; i < interfaces.length; i++) {
                int flags = interfaces[i].getModifiers();
                if (!Modifier.isPublic(flags)) {
                    String name = interfaces[i].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");
                    }
                }
            }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/0dab0fb138c3829c8bf6ef3b552a8a73.html