Java 动态代理机制分析及扩展,第 2 部分
2010-02-24 00:00:00 来源:WEB开发网得到代理类的字节码,接下来就可以动态装载该类了。这部分由 ProxyEx 类的 defineClassHelper 函数完成。该函数分两步进行:第一步通过反射获取父类 Proxy 的静态私有方法 defineClass0;第二步传入字节码数组及其他相关信息并反射调用该方法以完成类的动态装载。
清单 14. ProxyEx 的静态方法 defineClassHelper
private static Class defineClassHelper( String pkg, String cName, byte[] codeSource )
throws Exception
{
Method defineClass = Proxy.class.getDeclaredMethod( "defineClass0",
new Class[] { ClassLoader.class,
String.class,
byte[].class,
int.class,
int.class } );
defineClass.setAccessible(true);
return (Class)defineClass.invoke( Proxy.class,
new Object[] { ProxyEx.class.getClassLoader(),
pkg.length()==0 ? cName : pkg+"."+cName,
codeSource,
new Integer(0),
new Integer(codeSource.length) } );
}
性能改进
原动态代理机制中对接口数组有一些有趣的特点,其中之一就是接口的顺序差异会在一定程度上导致生成新的代理类,即使其实并无必要。其中的原因就是因为缓存表是以接口名称列表作为关键字,所以不同的顺序就意味着不同的关键字,如果对应的关键字不存在,就会生成新但是作用重复的代理类。在 ProxyEx 类中,我们通过主动排序避免了类似的问题,提高动态生成代理类的效率。而且,如果发现数组中都是接口类型,则直接调用父类 Proxy 的静态方法 getProxyClass 生成代理类,否则才通过扩展动态代理机制生成代理类,这样也一定程度上改进了性能。
更多精彩
赞助商链接