本文希望将 Java 动态代理机制从接口扩展到类,使得类能够享有与接口类似的动态代理支持。
设计及特点
新扩展的类名为 ProxyEx,将直接继承于 java.lang.reflect.Proxy,也声明了与原 Proxy 类中同名的 public 静态方法,目的是保持与原代理机制在使用方法上的完全一致。
图 1. ProxyEx 类继承图
与原代理机制最大的区别在于,动态生成的代理类将不再从 Proxy 类继承,改而继承需被代理的类。由于 Java 的单继承原则,扩展代理机制所支持的类数目不得多于一个,但它可以声明实现若干接口。包管理的机制与原来相似,不支持一个以上的类和接口同时为非 public;如果仅有一个非 public 的类或接口,假设其包为 PackageA,则动态生成的代理类将位于包 PackageA;否则将位于被代理的类所在的包。生成的代理类也被赋予 final 和 public 访问属性,且其命名规则类似地为“父类名 +ProxyN”(N 也是递增的阿拉伯数字)。最后,在异常处理方面则与原来保持完全一致。
图 2. 动态生成的代理类的继承图
模板
通过对 Java 动态代理机制的推演,我们已经获得了一个通用的方法模板。可以预期的是,通过模板来定制和引导代理类的代码生成,是比较可行的方法。我们将主要使用两个模板:类模板和方法模板。
清单 1. 类模板
package &Package;
final public class &Name &Extends &Implements
{
private java.lang.reflect.InvocationHandler handler = null;
&Constructors
&Methods
}
类模板定制了代理类的代码框架。其中带“&”前缀的标签位被用来引导相应的代码替换。在此预留了包(&Package)、类名(&ClassName)、类继承(&Extends)、接口实现(&Implements)、构造函数集(&Constructors)及方法集(&Methods)的标签位。类模板还同时声明了一个私有型的调用处理器对象作为类成员。
清单 2. 方法模板
&Modifiers &ReturnType &MethodName(&Parameters) &Throwables
{
java.lang.reflect.Method method = null;
try {
method = &Class.getMethod( "& MethodName