设为首页 加入收藏

TOP

Java动态代理深入解析(三)
2017-02-08 08:16:41 】 浏览:370
Tags:Java 动态 代理 深入 解析
? ? ? * Find or create the proxy class cache for the class loader.
? ? ? ? */
? ? ? ? Map, Object> cache;
? ? ? ? synchronized (loaderToCache) {
? ? ? ? ? ? cache = loaderToCache.get(loader);
? ? ? ? ? ? if (cache == null) {
? ? ? ? ? ? ? ? cache = new HashMap<>();
? ? ? ? ? ? ? ? loaderToCache.put(loader, cache);
? ? ? ? ? ? }
? ? ? ? ? ? /*
? ? ? ? ? ? * This mapping will remain valid for the duration of this
? ? ? ? ? ? * method, without further synchronization, because the mapping
? ? ? ? ? ? * will only be removed if the class loader becomes unreachable.
? ? ? ? ? ? */
? ? ? ? }


? ? ? ? /*
? ? ? ? * Look up the list of interfaces in the proxy class cache using
? ? ? ? * the key.? This lookup will result in one of three possible
? ? ? ? * kinds of values:
? ? ? ? *? ? null, if there is currently no proxy class for the list of
? ? ? ? *? ? ? ? interfaces in the class loader,
? ? ? ? *? ? the pendingGenerationMarker object, if a proxy class for the
? ? ? ? *? ? ? ? list of interfaces is currently being generated,
? ? ? ? *? ? or a weak reference to a Class object, if a proxy class for
? ? ? ? *? ? ? ? the list of interfaces has already been generated.
? ? ? ? */
     //看看缓存里有没有,如果有就直接取出来然后return,否则判断根据pendingGenerationMarker判断是否有其它线程正在生成当前的代理类,如果有则cache.wait()等待,如果没有则创建。


? ? ? ? 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"

首页 上一页 1 2 3 4 5 下一页 尾页 3/5/5
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇从JVM的角度来看单例模式 下一篇Java虚拟机字节码执行引擎

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目