jdk动态代理和cglib动态代理

jdk动态代理

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

核心API

java.lang.reflect.Proxy  框架

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

java.lang.reflect.InvocationHandler 函数

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

java.lang.ClassLoader spa

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

实现一个动态代理

代码实现:点击下载代理

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

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.代理对象是怎么生成的blog

由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类实现

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

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

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

总结

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

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

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

相关文章
相关标签/搜索