CGLib动态代理

导入jar包

asm-7.0.jar
cglib-3.2.10.jar

仍然以加法运算为例

//定义目标对象的类和方法
class CalculatorService{
	public int add(int a, int b) {
		int result = a+b;
		return result;
	}
}

public class ProxyFactory {
	static CalculatorService target; //目标对象
	//MethodInterceptor接口继承自Callback接口
	static Callback callback=new MethodInterceptor() {
		
		@Override
		public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
			//第一个参数对象是代理对象 
			System.out.println(target+"111"+proxy.getClass().getName());
			return 0;  //将来调用的目标方法的返回值
		}
	};
	
	
	public static Object getProxy(CalculatorService target){
		ProxyFactory.target=target;
		Enhancer enhancer=new Enhancer();
		enhancer.setSuperclass(target.getClass());
		//用CGLib的方式实现动态代理,所生成的对象对应的类,是目标对象对应的CalculatorService类的子类;jdk动态代理是同级的关系
		enhancer.setCallback(callback);
		return enhancer.create();
	}
}

class Test {	
	
	public static void main(String[] args) {		
		
		CalculatorService calculatorService = (CalculatorService)ProxyFactory.getProxy(new CalculatorService());		
		int result=calculatorService.add(1, 2);
		System.out.println(result);
	}
}

运行测试类,输出结果

com.replace.cg.CalculatorService@121714c111com.replace.cg.CalculatorService$$EnhancerByCGLIB$$481ab534
0

修改内部类中的代码,关联需求

static Callback callback=new MethodInterceptor() {
		
	@Override
	public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
		//第一个参数对象是代理对象 
		String name=method.getName();
		System.out.println(target.getClass().getName()+" the "+name+" method begins");
		Object result=method.invoke(target, args);
		System.out.println(target.getClass().getName()+" the result of "+name+" method is:"+result);
		System.out.println(target.getClass().getName()+" the "+name+" method ends");
		return result;  //将来调用的目标方法的返回值
	}
};

再次运行测试类,输出

com.replace.cg.CalculatorService the add method begins
com.replace.cg.CalculatorService the result of add method is:3
com.replace.cg.CalculatorService the add method ends
3

接下来我们要证明,目标对象CalculatorService target和测试类中的代理对象new CalculatorService()到底是什么关系
我们需要打印出产生动态对象的类,这个类也是临时的,
//测试类的主方法中添加如下代码

//生成使用CGlib创建动态代理对象的class文件
System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "D:\\class");

控制台输出

CGLIB debugging enabled, writing to 'D:\class'
com.replace.cg.CalculatorService the add method begins
com.replace.cg.CalculatorService the result of add method is:3
com.replace.cg.CalculatorService the add method ends
3

D盘生成如下路径文件
在这里插入图片描述
复制文件到lib双击
在这里插入图片描述
这个文件对应的是是动态产生代理对象的类,观察代码可知extends
这就可以证明CGLib动态代理对象产生的动态代理对象 我们目标类对象的子对象

总结
研究使用CGLib实现动态代理

CGLib动态代理
程序执行时通过ASM(开源的Java字节码编辑库,操作字节码)jar包动态地为被代理类生成一个代理子类,通过该代理子类创建代理对象,由于存在继承关系,所以父类不能使用final修饰。

JDK动态代理与CGLib动态代理区别:
1、JDK动态代理基于接口实现,所以实现JDK动态代理,必须先定义接口;CGLib动态代理基于类实现;
2、JDK动态代理机制是委托机制,委托hanlder调用原始实现类方法;CGLib则使用继承机制,被代理类和代理类是继承关系,所以代理类是可以赋值给被代理类的,如果被代理类有接口,那么代理类也可以赋值给接口。

动态代理优点:
1、静态代理在程序执行前需手动创建代理类,如果需要很多代理类,每一个都手动创建不仅浪费时间,而且可能产生大量重复性代码,此时我们就可以采用动态代理。
2、动态代理通过InvocationHandler接口invoke方法或MethodIn

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值