java 动态代理
2019-04-09 本文已影响0人
风吟空城
java动态代理主要是通过InvocationHandler接口和Proxy类结合实现。下面逐一解释下两者的用法。
InvocationHandler
InvocationHandler接口源码
/**
* {@code InvocationHandler} is the interface implemented by
* the <i>invocation handler</i> of a proxy instance.
*
* <p>Each proxy instance has an associated invocation handler.
* When a method is invoked on a proxy instance, the method
* invocation is encoded and dispatched to the {@code invoke}
* method of its invocation handler.
*
* @author Peter Jones
* @see Proxy
* @since 1.3
*/
public interface InvocationHandler {
因为找不到合适的称呼,所以把invocation handler
统一翻译为调用处理程序
,作为名词使用。
代理类实例的调用处理程序
都必须实现InvocationHandler接口,每个代理类实例中都有一个与之关联调用处理程序
。当我们通过代理类实例调用一个方法的时候,这个方法调用就会被编码、转发到调用处理程序
的invoke
方法。
Invoke方法
invoke源码:
/**
* Processes a method invocation on a proxy instance and returns
* the result. This method will be invoked on an invocation handler
* when a method is invoked on a proxy instance that it is
* associated with.
*
* @param proxy the proxy instance that the method was invoked on
*
* @param method the {@code Method} instance corresponding to
* the interface method invoked on the proxy instance. The declaring
* class of the {@code Method} object will be the interface that
* the method was declared in, which may be a superinterface of the
* proxy interface that the proxy class inherits the method through.
*
* @param args an array of objects containing the values of the
* arguments passed in the method invocation on the proxy instance,
* or {@code null} if interface method takes no arguments.
* Arguments of primitive types are wrapped in instances of the
* appropriate primitive wrapper class, such as
* {@code java.lang.Integer} or {@code java.lang.Boolean}.
*/
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable;
参数解释
- proxy 真实对象的真实代理对象。
- method 与代理实例上调用的接口方法相对应的方法实例。
- args 代理实例调用的方法的参数值,是一个对象数组。
Proxy
Proxy提供了很多静态方法来创建动态代理类和代理类实例,而且它还是所有它创建的动态代理类的超级父类。
/**
* {@code Proxy} provides static methods for creating dynamic proxy
* classes and instances, and it is also the superclass of all
* dynamic proxy classes created by those methods.
*/
public class Proxy implements java.io.Serializable {
和InvocationHandler
结合使用时,主要使用的静态方法是newProxyInstance
。
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
throws IllegalArgumentException {
...
}
-
loader: 用哪个类加载器去加载代理对象
-
interfaces:动态代理类需要实现的接口
-
h:动态代理方法在执行时,会调用h里面的invoke方法去执行
demo
接口代码
public interface People {
/**
* 晚餐吃什么
* @return 食物
*/
String dinner();
}
实现类
public class ItWorker implements People {
@Override
public String dinner() {
return "KFC";
}
}
调用处理程序
public class PeopleHandler implements InvocationHandler {
private Object obj;
PeopleHandler() {
}
PeopleHandler(Object obj) {
this.obj = obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return method.invoke(obj, args);
}
}
PeopleHandler
就是我们所说的调用处理程序
,会在代理类创建代理实例时,作为参数(测试类中的peopleHandler
)使用。通过demo可以更好的理解InvocationHandler
的参数及功能。
测试类
public class PeopleTest {
public static void main(String [] args){
//真实对象
People people = new ItWorker();
//调用处理程序
PeopleHandler peopleHandler = new PeopleHandler(people);
//代理
People proxy = (People) Proxy.newProxyInstance(peopleHandler.getClass().getClassLoader(),
people.getClass().getInterfaces(), peopleHandler);
System.out.println(proxy.dinner());
}
}