JDK动态代理和Cglib动态代理


 Object java.lang.reflect.Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces,InvocationHandler h) throwsIllegalArgumentException

      Returns an instance of a proxy class for the specified interfaces that dispatches method invocations to the specified invocation handler

上面这句的意思是该方法返回一个指定接口的一个代理类, 这个接口将方法调用派遣到指定的调用句柄, 所谓invocation handler也就是代理。

很明显JDK中要被动态代理的类需要实现一个接口。

public class RobotProxy implements InvocationHandler {

	private Object target;
	
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		System.out.println("Robot proxy access");
		Object result = method.invoke(target, args);
		System.out.println("Robot proxy leave");
		return result;
	}

	public Object getInstance(Object target){
		this.target = target;
		return Proxy.newProxyInstance(target.getClass().getClassLoader(), 
				target.getClass().getInterfaces(), this);
	}

}
使用代理

Robot robot = new Robot();
		
RobotProxy rProxy = new RobotProxy();
Language iRobot = (Language)rProxy.getInstance(robot);
iRobot.spell("hello world, my name is an intelegent ROBOT!");

这种代理返回的是接口类型

Robot iRobot = (Robot)rProxy.getInstance(robot);
改成上面代码后会报错

Exception in thread "main" java.lang.ClassCastException: $Proxy0 cannot be cast to Robot
    at RobotTest.main(RobotTest.java:13)


CGLIB则是通过生成类的子类来实现的动态代理, 这样就允许不实现接口也能被代理。

public class RobotCglibProxy implements MethodInterceptor {

	private Object target;
	
	public Object getInstance(Object target){
		this.target = target;
		Enhancer enhancer = new Enhancer();
		enhancer.setSuperclass(target.getClass());
		enhancer.setCallback(this);
		return enhancer.create();
	}
	
	@Override
	public Object intercept(Object obj, Method method, Object[] args,
			MethodProxy proxy) throws Throwable {
		System.out.println("Robot cglib proxy access");
		Object result = proxy.invoke(target, args);
		System.out.println("Robot cglib proxy leave");
		return result;
	}

}
为了测试我把接口去掉

public class Robot {

	public void spell(String words) {
		System.out.println(words);
	}
	
	public String getRobotName(){
		return "Timi";
	}

}
Robot robot = new Robot();
RobotCglibProxy rcProxy = new RobotCglibProxy();
Robot icRobot = (Robot)rcProxy.getInstance(robot);
icRobot.spell("hello world, my name is an intelegent ROBOT!");
System.out.println("Robot name is :"+icRobot.getRobotName());



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

dyyaries

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值