CGLIB动态代理
- 一:CGLIB(Code Generation Library)是一个基于ASM的字节码生成库,它允许我们在运行时对字节码进行修改和动态生成。CGLIB通过继承方式实现代理。
- 二:使用cglib需要引入cglib的jar包,如果你已经有spring-core的jar包,则无需引入,因为spring中包含了cglib。
- 三:cglib代理无需实现接口,通过生成类字节码实现代理,比反射稍快,不存在性能问题,但cglib会继承目标对象,需要重写方法,所以目标对象不能为final类
话不多说,直接上代码
package com.zdp.zdp.cglibPractice;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
/**
* @author daniel
* @date 2019-05-01 21:44
*/
public class CglibProxy implements MethodInterceptor {
//保存被代理的对象
private Object target;
public CglibProxy(Object target) {
this.target = target;
}
//生成代理对象
public Object createCgLibProxy(){
//工具类
Enhancer enhancer=new Enhancer();
//设置被代理的对象,也可以理解为设置父类,因为动态代理类是继承了被动态代理类。
enhancer.setSuperclass(target.getClass());
//设置回调函数
enhancer.setCallback(this);
//创建子类的动态代理类对象
return enhancer.create();
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("01:打开冰箱门~~~~");
method.invoke(target,objects);
System.out.println("03:关闭冰箱门~~~~");
return null;
}
}
class test{
public static void main(String[] args) {
//新建被代理类的对象
CglibPractice cglibPractice=new CglibPractice();
//生成代理类对象
CglibPractice cglibPracticeProxy=(CglibPractice)new CglibProxy(cglibPractice).createCgLibProxy();
cglibPracticeProxy.doIt();
//控制台输出内容
/**
*01:打开冰箱门~~~~
* 02:把大象塞进去~~~~
* 03:关闭冰箱门~~~~
**/
}
}
java原生动态代理类和Cglib的区别
- 1.JDK动态代理是实现了被代理对象的接口,Cglib是继承了被代理对象。
- 2.JDK和Cglib都是在运行期生成字节码,JDK是直接写Class字节码,Cglib使用ASM框架写Class字节码,Cglib代理实现更复杂,生成代理类比JDK效率低。
- 3.JDK调用代理方法,是通过反射机制调用,Cglib是通过FastClass机制直接调用方法,Cglib执行效率更高。Cglib底层将方法全部存入一个数组中,通过数组索引直接进行方法调用
- 4.代理类将被代理类作为自己的父类并为其中的非final委托方法创建两个方法,一个是与委托方法签名相同的方法(重写机制),它在方法中会通过super调用委托方法;另一个是代理类独有的方法。在代理方法中,它会判断是否存在实现了MethodInterceptor接口的对象,若存在则将调用intercept方法对委托方法进行代理