JDK动态代理
本文主要讲解的是JDK动态代理的使用方法
JDK动态代理只能代理接口。
java.lang.reflect.Proxy为JDK的代理类,它为创建动态代理类和实例提供了一些静态方法,
并且它是所有用这些方法创建出来的动态代理类的父类。
以下是Proxy类源码注释中提供的创建动态代理类的两种方法:
<p>To create a proxy for some interface {@code Foo}:
* <pre>
第一种方法:
* InvocationHandler handler = new MyInvocationHandler(...);
* Class proxyClass = Proxy.getProxyClass(
* Foo.class.getClassLoader(), new Class[] { Foo.class });
* Foo f = (Foo) proxyClass.
* getConstructor(new Class[] { InvocationHandler.class }).
* newInstance(new Object[] { handler });
* </pre>
* or more simply:
第二种更简洁的方法:
* <pre>
* Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),
* new Class[] { Foo.class },
* handler);
* </pre>
下面再介绍一下java.lang.reflect.InvocationHandler接口:
它是一个代理实例的调用处理器,每一个代理实例都有一个相关的调用处理器,
当一个方法在代理实例上被调用时,方法调用将会被编码并且转发到它的调用处理器的invoke方法上。
我们自己编写的调用处理器必须实现此接口,并且重写其中的invoke方法。
接下来我们来写一些代码来尝试一下JDK动态代理的流程:
第一步:
需要注意的是JDK动态代理的对象必须是interface类型的即接口。
所以我们先创建一个简单的接口:
public interface Fruit { void say(); }
再编写一个它的实现类:
public class Apple implements Fruit { @Override public void say() { // TODO Auto-generated method stub System.out.println("I am apple"); } }
接下来编写一个调用处理器:
public class CustomInvocationHandler implements InvocationHandler {
private Object object;
public CustomInvocationHandler(Object obj){
this.object = obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("方法调用前");
Object result = method.invoke(object, args);
System.out.println("方法调用后");
return result;
}
}
最后编写一个main方法来测试:
public class JDKproxy {
public static void main(String[] args) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
InvocationHandler handler = new CustomInvocationHandler(new Apple());
// 第一种方法:
// Class<?> proxyClass = Proxy.getProxyClass(
// Fruit.class.getClassLoader(), new Class[] { Fruit.class });
// Fruit f = (Fruit) proxyClass.
// getConstructor(new Class[] { InvocationHandler.class }).
// newInstance(new Object[] { handler });
// f.say();
// 第二种方法:
Fruit f = (Fruit) Proxy.newProxyInstance(Fruit.class.getClassLoader(),new Class[] { Fruit.class },handler);
f.say();
}
}
运行一下,看一下测试结果是:
方法调用前
I am apple
方法调用后
以上就是JDK动态代理的使用方法。