在运行时期能够按照Java虚拟机规范对class文件的组织规则生成对应的二进制字节码。当前有不少开源框架能够完成这些功能,如ASM,Javassist。java
动态代理机制详解(JDK 和CGLIB,Javassist,ASM)缓存
ASM,Javassist:在代码里生成字节码,并动态地加载成class对象、建立实例。即在运行期系统中,遵循Java编译系统组织.class文件的格式和结构,生成相应的二进制数据,而后再把这个二进制数据加载转换成对应的类,这样,就完成了在代码中,动态建立一个类的能力了。框架
ASM:ui
ASM 是一个 Java 字节码操控框架。它可以以二进制形式修改已有类或者动态生成类。ASM 能够直接产生二进制 class 文件,也能够在类被加载入 Java 虚拟机以前动态改变类行为。ASM 从类文件中读入信息后,可以改变类行为,分析类信息,甚至可以根据用户要求生成新类。编码
不过ASM在建立class字节码的过程当中,操纵的级别是底层JVM的汇编指令级别,这要求ASM使用者要对class组织结构和JVM汇编指令有必定的了解。lua
Javassist:直接使用java编码的形式,不须要了解虚拟机指令.net
JDK动态代理,CGLIB:不用写JVM的汇编指令和类的java编码,经过实现接口和继承的方式建立。代理
JDK动态代理: 某个类必须有实现的接口,而生成的代理类也只能代理某个类接口定义的方法。若是某个类没有实现接口,那么这个类就不能同JDK产生动态代理了。htm
CGLIB:经过继承完成并且效率比JDK动态代理高。对象
jdk动态代理是由java内部的反射机制来实现的,cglib动态代理底层则是借助asm来实现的。总的来讲,反射机制在生成类的过程当中比较高效,而asm在生成类以后的相关执行过程当中比较高效(能够经过将asm生成的类进行缓存,这样解决asm生成类过程低效问题)。还有一点必须注意:jdk动态代理的应用前提,必须是目标类基于统一的接口。若是没有上述前提,jdk动态代理不能应用。由此能够看出,jdk动态代理有必定的局限性,cglib这种第三方类库实现的动态代理应用更加普遍,且在效率上更有优点。。
http://blog.csdn.net/heyutao007/article/details/49738887
java动态代理:
好比如今想为RealSubject这个类建立一个动态代理对象,JDK主要会作如下工做:
1. 获取 RealSubject上的全部接口列表;
2. 肯定要生成的代理类的类名,默认为:com.sun.proxy.$ProxyXXXX ;3. 根据须要实现的接口信息,在代码中动态建立 该Proxy类的字节码;
4 . 将对应的字节码转换为对应的class 对象;
5. 建立InvocationHandler 实例handler,用来处理Proxy全部方法调用;
6. Proxy 的class对象 以建立的handler对象为参数,实例化一个proxy对象
1.Interface A
2.Class B impl A
3.MyInvocationHandler impl InvocationHandler{
private Object target;//B
invoke(...){
method.invoke(target, args);
4.Class main(){
A a = new B();
InvocationHandler h = new MyInvocationHandler(a);
A proxy = (A)Proxy.newProxyInstance(a.getClass().getClassLoader(), a.getClass().getInterfaces(), h);