代理模式
参考:《JAVA 程序性能优化》
将代理类用于实现延迟加载,可以有效地提升系统的启动速度。
延迟加载的核心思想是:如果当前并没有使用这个组件,则不需要真正地初始化它,使用一个代理对象替代它的原有位置,只要在真正需要使用的时候,才对它进行加载。
代理模式的实现如下:
假设有一个接口 IDBQuery,它只有一个 request() 方法:
1 | public interface IDBQuery { |
DBQuery 的实现如下,它是一个重量级对象,构造会比较慢:
1 | public class DBQuery implements IDBQuery { |
代理类 DBQueryProxy 是轻量级对象,创建很快,用于替代 DBQuery 的位置:
1 | public class DBQueryProxy implements IDBQuery { |
最后,主函数如下,它引用 IDBQuery 接口,并使用代理类工作:
1 | public class Main { |
public static void main(String[] args) {
IDBQuery query = new DBQuery();
Class[] cs = {IDBQuery.class};
InvocationHandler h = new DBQueryInvocationHandler(query);
// JDK 动态代理,JDK 动态代理的类必须实现一个接口,而且生成的代理类是其接口的实现类,也就是被代理的类的兄弟类,由 JDK 内部实现
IDBQuery queryProxy = (IDBQuery) Proxy.newProxyInstance(IDBQuery.class.getClassLoader(), cs, h);
System.out.println("proxy class name: " + queryProxy.getClass().getName());
System.out.println("proxy class simple name: " + queryProxy.getClass().getSimpleName());
System.out.println(queryProxy.request());
}
InvocationHandler 接口只有一个方法,即 invoke() 方法!它是对代理对象所有方法的唯一实现。也就是说,无论你调用代理对象上的哪个方法,其实都是在调用 InvocationHandler 的 invoke() 方法。
InvocationHandler 的 invoke() 方法
InvocationHandler 的 invoke() 方法的参数有三个:
Object proxy:代理对象,也就是 Proxy.newProxyInstance() 方法返回的对象,通常我们用不上它。
具体查看:
Understanding “proxy” arguments of the invoke method of java.lang.reflect.InvocationHandlerMethod method:表示当前被调用方法的反射对象,例如 queryProxy.request(),那么 method 就是 request() 方法的反射对象。
Object[] args:表示当前被调用方法的参数,当然 queryProxy.request() 这个调用是没有参数的,所以 args 是一个零长数组。
最后要说的是 invoke() 方法的返回值为 Object 类型,它表示当前被调用的方法的返回值,当然 queryProxy.request() 方法是没有返回值的,所以 invoke() 返回的就必须是 null 了。
如果长时间无法加载,请针对 disq.us | disquscdn.com | disqus.com 启用代理