`
modabobo
  • 浏览: 510245 次
文章分类
社区版块
存档分类
最新评论

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());



分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics