java设计模式之 代理模式( 二 )

[] interfaces,InvocationHandler h)throws IllegalArgumentException{Objects.requireNonNull(h);final Class[] intfs = interfaces.clone();final SecurityManager sm = System.getSecurityManager();if (sm != null) {checkProxyAccess(Reflection.getCallerClass(), loader, intfs);}/** Look up or generate the designated proxy class.*/Class cl = getProxyClass0(loader, intfs);/** Invoke its constructor with the designated invocation handler.*/try {if (sm != null) {checkNewProxyPermission(Reflection.getCallerClass(), cl);}final Constructor cons = cl.getConstructor(constructorParams);final InvocationHandler ih = h;if (!Modifier.isPublic(cl.getModifiers())) {AccessController.doPrivileged(new PrivilegedAction() {public Void run() {cons.setAccessible(true);return null;}});}return cons.newInstance(new Object[]{h});} catch (IllegalAccessException|InstantiationException e) {throw new InternalError(e.toString(), e);} catch (InvocationTargetException e) {Throwable t = e.getCause();if (t instanceof RuntimeException) {throw (RuntimeException) t;} else {throw new InternalError(t.toString(), t);}} catch (NoSuchMethodException e) {throw new InternalError(e.toString(), e);}}
可以看到 , 获得代理类的代码是Class cl = (, intfs);
并由此获得代理类的构造函数 , 生成代理类的实例返回给该方法的调用者 。
继续跟进()方法:
/***Generate a proxy class.Must call the checkProxyAccess method* to perform permission checks before calling this.*/private static Class getProxyClass0(ClassLoader loader,Class... interfaces) {if (interfaces.length > 65535) {throw new IllegalArgumentException("interface limit exceeded");}// If the proxy class defined by the given loader implementing// the given interfaces exists, this will simply return the cached copy;// otherwise, it will create the proxy class via the ProxyClassFactoryreturn proxyClassCache.get(loader, interfaces);}
通过注释可以看到 , 代理类是从 取的 , 如果代理类已经通过实现给定接口的类加载器创建了 , 则返回缓存中的该类的副本;否则将通过创建代理类 。
我们查看的初始化代码
/*** a cache of proxy classes*/private static final WeakCache[], Class>proxyClassCache = new WeakCache<>(new KeyFactory(), new ProxyClassFactory());
可以发现是个用来缓存代理类的类变量[ final] , 大家知道类变量的特点是与类一一对应 , 在一个虚拟机中类只有一个 , 对应着在一个虚拟机中类变量也只有一个【这是一个单例模式】 , 且在此处 , 在Proxy类被加载的时候就赋值了 。
注意这里是虚引用 。虚引用并不会决定对象的生命周期 。如果一个对象仅持有虚引用 , 那么它就和没有任何引用一样 , 在任何时候都可能被垃圾回收器回收 。具体请参考 Java:对象的强、软、弱和虚引用
在赋值操作的参数中有()这么一个构造函数 , 这个是动态代理中的关键:生成代理类的类文件字节码 。继续跟进去 , 找到代理类的生成之处了:
/*** A factory function that generates, defines and returns the proxy class given* the ClassLoader and array of interfaces.* 根据给定的类加载器和接口数组生成代理类的工厂类*/private static final class ProxyClassFactoryimplements BiFunction[], Class>{// prefix for all proxy class names代理类的前缀private static final String proxyClassNamePrefix = "$Proxy";// next number to use for generation of unique proxy class names//代理类编号 , 这里使用的是AtomicLong保证线程安全private static final AtomicLong nextUniqueNumber = new AtomicLong();@Overridepublic Class