CGLib实现动态代理

目录

CGLib动态代理

 JDK动态代理与CGLib动态代理区别:

 动态代理优点:


 

CGLib动态代理

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


过程

1.首先导入jar包                                                     

2.定义一个接口

public interface ICalculatorService {
	int add(int a,int b);	
	int sub(int a,int b);
	int mul(int a,int b);	
	int div(int a,int b);
}

3.接口实现类

public class CalculatorService implements ICalculatorService {

	@Override
	public int add(int a, int b) {
		int result = a+b;
		return result;
	}
	@Override
	public int sub(int a, int b) {
		int result = a-b;
		return result;
	}
	@Override
	public int mul(int a, int b) {
		int result = a*b;
		return result;
	}
	@Override
	public int div(int a, int b) {
		int result = a/b;
		return result;
	}
}

4.CGlib

import java.lang.reflect.Method;
import net.sf.cglib.proxy.Callback;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

public class ProxyFactory {

	static ICalculatorService target;// 目标对象
	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() + "--"+name + "--method begins.");
			System.out.println(target.getClass().getName() + ":Parameters of the " + name + " method: [" + args[0] + ","
					+ args[1] + "]");
			Object result = method.invoke(target, args);
			System.out.println(target.getClass().getName() + ":Result of the " + name + " method:" + result);
			System.out.println(target.getClass().getName() + ":The " + name + " method ends.");
			return result;
		}
	};

	public static Object getProxy(ICalculatorService target) {

		ProxyFactory.target = target;
		Enhancer enhancer = new Enhancer(); // Enhancer类 类似于JDK调用add方法增加了一些打印的信息
		enhancer.setSuperclass(target.getClass()); // superclass
		enhancer.setCallback(callback);
		return enhancer.create(); // 代理谁,返回的代理对象
	}
}

5.测试类

public class Test {
	public static void main(String[] args) {
		CalculatorService cService = (CalculatorService) ProxyFactory.getProxy(new CalculatorService());
		System.out.println("cService--------->" + cService.getClass().getName());
		int result = cService.add(1, 2); // cService存放的是由Proxy创建的实现的ICalculatorService的一个匿名内部类
		// cService.add(1, 2);调用的是由proxy类创建的匿名内部类对象中的add方法
		System.out.println(result);
	}
}

运行结果:

注意:CGlib生成的动态代理对象所对应的类是目标对象CalculatorService类的子类,两者是父子关系

 JDK动态代理与CGLib动态代理区别:

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

 动态代理优点:

1、静态代理在程序执行前需手动创建代理类,如果需要很多代理类,每一个都手动创建不仅浪费时间,而且可能产生大量重复性代码,此时我们就可以采用动态代理。
2、动态代理通过InvocationHandler接口invoke方法或MethodInterceptor接口intercept方法为被代理对象中的方法增加额外功能,这种方式比静态代理中通过代理类逐一为被代理对象中的方法增加额外功能,更加的灵活。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值