`
lvwenwen
  • 浏览: 934695 次
  • 性别: Icon_minigender_1
  • 来自: 魔都
社区版块
存档分类
最新评论

读的JDK动态代理源码(代理类)

阅读更多
读的JDK动态代理源码(代理类) 

2010-05-21 11时51分07秒|分类: 设计模式 | 字号 订阅
读源码,怕过两天又忘记了,还是记录下吧......

动态代理最重要的实现就是Proxy.newInstance,那我们当前直接看这个方法扩展功能

(ClassLoader的加载,
       类<?> []接口,
       InvocationHandler的公共静态对象newProxyInstance  IllegalArgumentException     {  如果(H == NULL){      抛出NullPointerException异常()/ /如果InvocationHandler的为空,抛异常  }





/
  * 查找或生成指定的代理类,这个方法里最主要的地方在这里,它直接透过调用。

CL = getProxyClass(装载机,接口);

/
  * 调用指定的调用其构造  {      构造函数的利弊= cl.getConstructor(constructorParams);      cons.newInstance回报(对象)(新的Object [] {H});  }(NoSuchMethodException E){      扔:新InternalError(e.toString());  }(IllegalAccessException E){      扔新InternalError(e.toString());  渔获(InstantiationException E){      扔:新InternalError(e.toString());  }渔获(InvocationTargetException E){      扔:新InternalError(e.toString());      } }














上面的方法,除了最重要的getProxyClass,其他都很容易理解.,那么下面开始读getProxyClass方法

<> getProxyClass公共静态类(ClassLoader的装载机,
                                         <>类...接口)
抛出IllegalArgumentException
    {
如果(interfaces.length> 65535){
     抛出新IllegalArgumentException(“接口超限”); / / JDK的想的果然比较到位,连界面传动的太多都想到了..〜!〜
}

类proxyClass = NULL; / /这个就是最后要生成的二进制码,首先初始化一下

/ *收集接口名称作为键使用缓存代理类* /
的String [] interfaceNames =新的String [interfaces.length]; / /这个存放的是对应的接口的名字......

设置interfaceSet =新的HashSet()/ / 这个HashSet的是为了检测接口重复记录的。

为(int i = 0;我<interfaces.length;我+){
     /
      * 检查类加载器可以解决这个名字
      *接口的同一类对象
      * /
     字符串InterfaceName中=接口[我]的getName()。
     类interfaceClass = NULL;
     尝试{
  interfaceClass = Class.forName的(InterfaceName中,虚假,装载机); / /建立对应接口的二进制码,第二个参数虚假表示,不需要初始化
     }(ClassNotFoundException异常){
     }
     (interfaceClass =接口[I])  新IllegalArgumentException(      接口[I] +“是从类加载器中不可见”);      }



     /
      * 验证的Class对象实际上代表
      *接口。
      * /
     如果(!interfaceClass.isInterface())  新IllegalArgumentException(      interfaceClass.getName()+“不是一个接口”);      }



     /
      * 确认该接口是不是      (interfaceSet.contains(interfaceClass)){   抛出新IllegalArgumentException(       “ 反复接口:”interfaceClass.getName());      }      interfaceSet.add(interfaceClass);






     interfaceNames [I] = InterfaceName中; / /这句就是把每个接口名放到interfaceNames的数组里......

/
  * 使用
  *键缓存(而不是他们的一类代理类
  *对象)作为代理接口的字符串表示形式是足够的,因为我们需要代理
  *接口是通过提供的名称解析
  *类加载器,它具有的优点是使用一个字符串
  类*表示一个隐式的弱
  *参考类。
  * /
对象的关键=

/ *
  查找或创建代理类的类加载器缓存。
  * /
地图缓存; / /放缓存的地图
同步(loaderToCache)     (地图)loaderToCache.get“(装载机);      (缓存== NULL){   缓存=新的HashMap();   loaderToCache.put(装载机,高速缓存);      }      /       * 为这个时间      *,这种映射将继续有效方法,没有进一步的同步,因为映射      *只会被删除,如果类装载器无法访问。      * /  }











/
  * 查找接口的代理类中使用缓存列表
  *键。此查找将导致三种可能的
  *种值之一:
  *空,如果目前还没有名单
  *接口的代理类的类加载器,
  *的pendingGenerationMarker的对象,如果一个代理类
  *列表接口正在生成,
  *或弱引用类对象,如果一个代理类
  *接口名单已经产生。
  * /
同步(缓存){
     /
      * 请注意,我们不必担心收割缓存
      *清除弱引用条目,因为如果一个代理类
      *已被垃圾收集,它的类装载器将一直
      *垃圾收集一样,所以整个高速缓存将被收割
      从loaderToCache地图*。
      * /
     {
  Object值=   (参考值的instanceof){       proxyClass =(A类)((参考)  (proxyClass = NULL){       / /代理类已经产生:返回      返回proxyClass,;   }否则如果(值== pendingGenerationMarker){ / /这里的pendingGenerationMarker是一个静态常量,表示新的对象()JDK给出的解释。是,如果代理正在建立,那么等待他       / /代理类,正在生成:等待它      试图{    cache.wait();       }的catch(InterruptedException的E){    /     * 类的一代,我们正在等待为    * 应采取1小,时间有限,所以我们可以放心地忽略    *线程中断。    * /       }       继续;   }否则{       /        *已没有这个接口列表的代理类       *产生或正在产生,所以我们会去和       *生成现在标记为挂起代       * /       中cache.put(关键,pendingGenerationMarker); / /如果缓存里获取到:的对应于键的值是NULL,那么,就建立一个对象的对象放进去上面说了, pendingGenerationMarker =新的对象();       休息;        } } ,而(真);  }





























尝试{
     弦乐proxyPkg = NULL; / /包中定义代理类,这个是代理类的包名

     / *
      记录
      *代理类将在同一个包中定义的一个非公开的代理接口的包。验证
      *所有非公开的代理接口在同一个包
      *
     / (I = 0;我<interfaces.length;我+){
  INT标志。  (!Modifier.isPublic(标志)){ / /如果不是公共的接口......


      名=接口[I]的getName();
      整数n = name.lastIndexOf('。');
      弦乐PKG =((N == -1)“:name.substring(0,N + 1)); / /注意这里的N +1的,其实是包括“。”的..比如com.cjb.proxy.Proxy ..它返回的就是“com.cjb.proxy。”注意最后的那个点

      如果(proxyPkg == NULL){
   proxyPkg = PKG;
      } {(pkg.equals(proxyPkg)!)
   抛出新IllegalArgumentException(
       “ 非公开的接口,从不同的包”);
      }
 
     } }

     如果(proxyPkg == NULL){/ /如果没有非公有制代理接口,这里可以看到,如果是公共的接口,对应代理类的包名就是“”,也就是没有包名
  proxyPkg =“”; / /使用未命名的包
     }

     {
  / *
   。*选择生成代理类的名称
   * /
  长民;
  同步(nextUniqueNumberLock){
      NUM =   proxyName = proxyPkg + proxyClassNamePrefix + NUM; / / proxyPkg,什么之前产生的包名,proxyClassNamePrefix $ Proxy1美元Proxy2发出Proxy3美元一直在增长的这样的话,就避免了重复。   /    * 验证类加载器尚未   *定义类与所选择的名称。   * /






  /
   * 生成指定的代理 ,proxyClassFile = ProxyGenerator.generateProxyClass(      proxyName接口);   尝试{       proxyClass = defineClass0(装载机proxyName,   proxyClassFile,0,proxyClassFile.length);   }(ClassFormatError E){       /        * 这里一个ClassFormatError指(限制在错误       *代理类生成的代码)有一些其他       *无效方面提供的代理参数       *类的创建(如虚拟机的限制       。*超过)       * /       抛出新IllegalArgumentException(e.toString());        } }      / /添加到设置的所有生成的代理类isProxyClass,     proxyClasses.put(proxyClass,空);

 

















} {
     /
      * 我们必须清理“等候的一代”的代理状态
      *级高速缓存条目,不知何故。如果成功
      *生成一个代理类,存储在缓存中(弱引用);
      *否则,删除保留项目。在所有情况下,通知
      此缓存中保留条目*所有服务员。
      * /
     同步(缓存){
  如果(proxyClass = NULL){
      中cache.put(关键,新的WeakReference(proxyClass));
  } {
      cache.remove(键);
  }
  cache.notifyAll();
    
} }
返回proxyClass;
    }

可以看到,我们想看的,最重要的生成二进制码的方法,是native的..读了这么多源码,都是一些前期处理.关键的地方不知道..当然,虽然没看到关键的地方,但是对于它前面的处理的学习,也是非常有用的..看看JDK是怎么处理重名问题的,怎么处理cache.等等..
分享到:
评论

相关推荐

    JDK动态代理源码

    JDK动态代理源码下载,动态产生代理,实现对【不同类】,【不同方法】的代理

    关于jdk动态代理的源码剖析

    对jdk中的动态代理执行过程进行了详细跟踪,并反编译了动态代理调用自动生成的代理类,并对其进行了详细讲解。

    java设计模式【之】JDK动态代理【源码】【场景:帮爸爸买菜】.rar

    java设计模式【之】JDK动态代理【源码】【场景:帮爸爸买菜】.rar /** * 代理模式 * 在开发者的角度来看,创建一个代理对象,提供给用户使用,避免用户直接访问真正的对象 * 在用户角度来看,就是普通的类方法...

    面试官:你说你懂动态代理,那你知道为什么JDK中的代理类都要继承Proxy吗?

    在动态代理学习(二)JDK动态代理源码分析中我已经讲JDK底层生成的字节码文件反编译成了java代码,如下: public final class proxy extends Proxy implements MyService { private static Method m1; private ...

    CGLIB 和 JDK生成动态代理类的区别

    NULL 博文链接:https://luyuanliang.iteye.com/blog/1137292

    两万字吐血总结,代理模式及手写实现动态代理(aop原理,基于jdk动态代理)

    jdk动态代理源码分析(通过该示例学会阅读源码的方法)2.jdk动态代理生成的代理类的源码3.总结三、手写实现jdk动态代理 一、代理模式 熟悉代理模式的可以直接点击目录第二章,jdk动态代理实现原理,本文的精髓所在,...

    JDK的动态代理(powernode 文档)(源代码)

    JDK的动态代理(powernode 文档)(源代码) JDK的动态代理(powernode 文档) 一、动态代理 1.1JDK动态代理 1.1.1 proxy 1.1.2 InvocationHandler ...1.1.11 生成的代理类源码 1.1.12 JDK动态代理的不足

    你必须会的 JDK 动态代理和 CGLIB 动态代理

    静态代理就是在程序运行之前,代理类字节码.class就已编译好,通常一个静态代理类也只代理一个目标类,代理类和目标类都实现相同的接口。 接下来就先通过 demo 进行分析什么是静态代理,当前创建一个 Animal 接口,...

    动态代理

    NULL 博文链接:https://zac110.iteye.com/blog/1272481

    java基础面试题目,常见的几个java面试题目:说一下java类集;JDK 和 JRE 有什么区别

    动态代理是怎么实现的;final 在 Java 中有什么作用; Java 中的 Math. round(-1. 5) 等于多少;String 属于基础的数据类型吗;String str="i"与 String str=new String("i")一样吗;如何将字符串反转;等等

    spring第四天.pdf

    8. 重点掌握JDK代理技术之产生代理对象和代理对象执行逻辑分析 9. 重点掌握Cglib代理技术之产生代理对象和代理对象执行逻辑分析 10. 认识Spring AOP中底层常用的一些核心类 11. 源码阅读之查找aop相关的...

    java毕业设计之休闲娱乐代理售票系统(springboot项目源码+LW+PPT+视频).zip

    java毕业设计之休闲娱乐代理售票系统(springboot项目源码+LW+PPT) 考虑到实际生活中休闲娱乐代理售票管理方面的需要以及对该系统认真的分析,将系统权限按管理员和用户这两类涉及用户划分。 (1)管理员功能需求 ...

    javanetty源码-java:jdk、guava、netty等源码阅读

    java netty 源码 项目由一下几个部分组成: ...java.lang.reflect,java动态代理,cglib代理,静态代理,三种代理模式; java集合类; java.util.concurrent; 3.netty: io基础,bio,nio,aio; netty服务端客户端demo;

    javasnmp源码-java_review:复习资料

    JDK动态代理和cgLib动态代理 ​ ​ ​ sprin创建bean过程 ​ ​ SpringMVC常用注解 ​ springMVC处理请求流程/工作流程 ​ ​ SpringMVC @RequestParam,@PathParam,@PathVariable等注解区别 ​ ...

    java中的三种代理模式

    该资源提供了三种代理模式的使用代码,其中包含每种模式的jar包、具体代码、Demo测试类,详细的注释帮助你来理解。

    Java JDK实例宝典

    全部代码出自电子工业出版社夏先波的《Java JDK实例宝典》一书,本书以J2SE 5.0为开发环境,选取Java应用的典型实例,循序渐进地介绍了Java语言的各种开发方法和技巧,实例代码注释详细规范,思路清晰。 第1章 ...

    基于java的saas多租户商城源码

    Jdk8+ Mysql5.7+ Maven Lombok(重要) 软件架构 核心框架:Spring Boot 2.4.0 安全框架:JwtPermission 3.1.1 前端:Ant Design Vue 1.6.2 持久层框架:MyBatis-Plus 3.4.1 关系型数据库: Mysql 8.0.22 数据库连接...

    java8源码-javase:Java

    用到了Jdk动态代理,以及Classloader。 resource 该模块主要用于Class和Classloader如何获取资源。 stream 用于JDK8的stream api用法。 string 用于写String类的用法。 iText-demo 主要来自 Jackson 使用Jackson和...

    java6string源码-dynamic-proxy:利用ASM、CGLIB、ByteBuddy、Javassist和JDKDynamicP

    java6string源码Java 动态代理 动态代理是 Java 开发人员生成代理对象的有用库。 该库利用了广泛的字节码生成方法,包括 1. 指南 1.1 先决条件 Maven 依赖: &lt;groupId&gt;net.neoremind&lt;/groupId&gt; &lt;artifactId&gt;dynamic...

    spring:Spring框架

    静态代理:由程序员创建或工具生成代理类的源码,再编译代理类,在程序运行前就产生了代理类的字节码文件,代理对象和目标对象的关系在程序运行前就决定了。 动态代理:在程序运行期间由JVM根据反射机制动态生成的,...

Global site tag (gtag.js) - Google Analytics