声明:这里我没有看源码,全凭代码操作和测试结果的理解。
JDK动态代理,主要包括两个组成部分,一个是代理逻辑
,一个是代理实体
。
作为代理逻辑类,必须要实现InvocationHandler
接口,因为要是不实现此接口,就没有办法利用Proxy的方法
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
throws IllegalArgumentException
来生成代理实体。代理实体一般会被强制转化为相应的接口类型,以调用相应的方法,执行代理逻辑中的内容。
并且因为代理逻辑类里是代理实体具体要执行的操作,所以一般都要传入被代理实体,来执行相关的逻辑。
ProxyLogic
(代理逻辑)实现InvocationHandler
接口,为生成代理实体做准备。
public class ProxyLogic implements InvocationHandler {
private Object target;
//target为被代理实体
public ProxyLogic(Object target) {
this.target=target;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
/* method.invoke(proxy,args); *///这里出现了死循环,不太理解,还望大佬指教
System.out.println("代理逻辑的载体!");
/* method.invoke(target); *///Exception in thread "main" java.lang.IllegalArgumentException: wrong number of arguments
Object invokeResult = method.invoke(target,args); //不报错
/* method.invoke(target,args,args); *///Exception in thread "main" java.lang.IllegalArgumentException: wrong number of arguments
return invokeResult;
}
}
HelloImp
类(被代理实体)实现了如下接口:
public interface Say {
void say(String str);
}
public interface Say {
void say(String str);
}
public interface SayMore {
void say(String str1,String str2);
}
public class HelloImp implements Hello,Say,SayMore {
@Override
public void sayHello() {
System.out.println("世界你好!");
}
@Override
public void say(String str) {
System.out.println("你说的是:"+str);
}
@Override
public void say(String str1, String str2) {
System.out.println("你说的是:"+str1+"和"+str2);
}
}
然后是测试类:
public static void main(String[] args) {
Hello hello = (Hello)Proxy.newProxyInstance(HelloImp.class.getClassLoader(), HelloImp.class.getInterfaces(),new learn.ProxyLogic(new HelloImp()));
hello.sayHello();
Say say = (Say)Proxy.newProxyInstance(HelloImp.class.getClassLoader(), HelloImp.class.getInterfaces(),new learn.ProxyLogic(new HelloImp()));
say.say("你好");
SayMore sayMore = (SayMore)Proxy.newProxyInstance(HelloImp.class.getClassLoader(), HelloImp.class.getInterfaces(),new learn.ProxyLogic(new HelloImp()));
sayMore.say("你好","世界");
}
输出结果:
代理逻辑的载体!
世界你好!
代理逻辑的载体!
你说的是:你好
代理逻辑的载体!
你说的是:你好和世界
所以可以理解,invoke()
中的Object[] args
参数,之所以要使用数组,就是为了适应被代理方法的参数个数。
初学者,还望读者老爷多指教