jdk动态代理和cglib动态代理

jdk动态代理

个人的理解,运行期间由JVM根据反射等机制动态的生成代理类

核心API

java.lang.reflect.Proxy  

所有动态代理类的父类,它提供了一组静态方法来为一组接口动态地生成代理类及其对象。

java.lang.reflect.InvocationHandler 

这是调用处理器接口,它自定义了一个 invoke 方法,通常在该方法中实现对委托类的访问

java.lang.ClassLoader 

这是类装载器类,负责将类的字节码装载到 Java 虚拟机(JVM)中并为其定义类对象,然后该类才能被使用

实现一个动态代理

代码实现:点击下载

一个典型的动态代理创建对象过程可分为以下四个步骤: 

1. 通过实现InvocationHandler接口创建自己的调用处理器 
IvocationHandler handler = new InvocationHandlerImpl(…);
2. 通过为Proxy类指定ClassLoader对象和一组interface创建动态代理类
Class clazz = Proxy.getProxyClass(classLoader,new Class[]{…});
3. 通过反射机制获取动态代理类的构造函数,其参数类型是调用处理器接口类型
Constructor constructor = clazz.getConstructor(new Class[]{InvocationHandler.class});
4. 通过构造函数创建代理类实例,此时需将调用处理器对象作为参数被传入 Interface Proxy = (Interface)constructor.newInstance(new Object[] (handler));

为了简化对象创建过程,Proxy类中的newInstance方法封装了2~4,只需两步即可完成代理对象的创建。 

核心问题

1.代理对象是怎么生成的

由Proxy完成, 在内部方法中调用ProxyGenerator类的静态方法generateProxyClass,这里是真正生成代理类class字节码的地方。 

2.InvocationHandler的invoke方法是由谁来调用的

生成的代理类ProxySubject继承Proxy类实现Subject接口,实现了Subject的方法,在实现方法中,调用处理器的invoke方法

3.真实实例的方法如何被调用的

InvocationHander的实现类只是通过代理类的构造函数注入后, 实现了对代理类中方法调用的拦截

而invoke方法利用反射调用的是真实对象的的方法(Object result=method.invoke(proxied,args))

总结

jdk动态代理只能代理接口,是因为生成的代理类本身 extends Proxy  implement  xxxInterface

 cglib动态代理

CGLib采用了asm框架的字节码技术,其原理是:

通过字节码技术为一个类创建子类,并在子类中采用方法拦截的技术拦截所有父类方法的调用,顺势织入横切逻辑

 核心API

 net.sf.cglib.proxy.Enhancer – 主要的增强类

net.sf.cglib.proxy.MethodInterceptor – 主要的方法拦截类,它是Callback接口的子接口,需要用户实现

net.sf.cglib.proxy.MethodProxy  -可以方便的实现对源对象方法的调用

实现一个动态代理

代码实现: 点击下载

核心问题

1.代理对象的生成过程由Enhancer类实现

1、生成代理类Class的二进制字节码;
2、通过Class.forName加载二进制字节码,生成Class对象;
3、通过反射机制获取实例构造,并初始化代理类对象。

2.如何调用真实实例的方法

通过FastClassInfo维护了委托类和代理类的FastClass,提出下标概念index,通过索引保存方法的引用信息,将原先的反射调用,转化为方法的直接调用
所以当调用methodProxy.invokeSuper方法时,实际上是调用代理类的CGLIB$add$0方法,CGLIB$add$0直接调用了委托类的add方法。

总结

cglib动态代理类,继承了委托类, 采用保存索引的方式调用委托类的方法

Jdk动态代理和cglib动态代理的区别

1、jdk动态代理生成的代理类和委托类实现了相同的接口;
2、cglib动态代理中生成的字节码更加复杂,生成的代理类是委托类的子类,且不能处理被final关键字修饰的方法;
3、jdk采用反射机制调用委托类的方法,cglib采用类似索引的方式直接调用委托类方法

 

posted @ 2017-02-24 21:17  liuconglin  阅读(811)  评论(0编辑  收藏  举报