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());
本文详细介绍了Java动态代理机制,包括基于反射的代理实现方式和CGLIB库如何通过生成类的子类实现动态代理。通过示例展示了如何使用代理对象调用接口方法,并讨论了两种技术在不同场景下的应用。
305

被折叠的 条评论
为什么被折叠?



