JDK 动态代理
2018-07-16 本文已影响4人
懒懒惰惰
DEMO
public interface HelloWorld {
void helloWorld();
}
public class HelloWorldImpl implements HelloWorld {
@Override
public void helloWorld() {
System.out.println("Hello World!");
}
}
public class InvocationHandlerImpl implements InvocationHandler {
//需要代理的对象
private Object object;
public InvocationHandlerImpl(Object object) {
this.object = object;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
long time = System.nanoTime();
System.out.println("Invocation of Method " + method.getName() + " start!");
method.invoke(object, args);
System.out.println("Invocation of Method " + method.getName() + " end! takes " + (System.nanoTime() - time) + " nanoseconds.");
return null;
}
}
public class DynamicProxyTest {
public static void main(String[] args) {
//代理对象
HelloWorld helloworld = new HelloWorldImpl();
InvocationHandler handler = new InvocationHandlerImpl(helloworld);
ClassLoader loader = helloworld.getClass().getClassLoader();
Class[] interfaces = helloworld.getClass().getInterfaces();
//创建代理类
HelloWorld proxyclz = (HelloWorld) Proxy.newProxyInstance(loader, interfaces, handler);
proxyclz.helloWorld();
}
}
Invocation of Method helloWorld start!
Hello World!
Invocation of Method helloWorld end! takes 289726 nanoseconds.
Process finished with exit code 0
实际上,proxyclz是继承真实对象接口的代理类,他的内部方法会通过反射的方式去调用handler的invoke方法.
动态代理原理图:
动态代理
其中代理类的创建是:
HelloWorld proxyclz = (HelloWorld) Proxy.newProxyInstance(loader, interfaces, handler);
最后会创建一个继承接口的代理类,实现了接口中的所有方法,所有方法均会反向调用handler的invoke的方法并传入当前调用method的method对象和入参如,上面例子中的proxy会有如下方法(伪代码)
public final void helloWorld()
{
Method method = Class.forName("HelloWorld").getMethod("helloWorld", new Class[0]);
handler.invoke(this, method, null);
}