Proxy从字义的理解上就是代理,实现代理的功能。从Proxy的设计模式的定义上来看,代理的意义在于我们可以通过代理类A来处理被代理类B所做的事情。使用代理,可以预处理消息、过滤消息、把消息转发给被代理的对象B,调用B的方法,最后可以做一些事后处理消息的工作。
简单的Proxy模式的实现:
事实上只需要一些简单的代码就可以实现代理。
public class SimpleProxyTest {
public static void main(String[] args) {
SimpleBase test = new SimpleTestImpl();
SimpleBase proxy = new SimpleProxyImpl(test);
proxy.myMethod(10);
}
}
interface SimpleBase
{
public void myMethod(Integer parm);
}
class SimpleTestImpl implements SimpleBase
{
public void myMethod(Integer parm)
{
if (parm > 0)
{
System.out.println("it is more than 0");
}
else
{
System.out.println("it is equal or less than 0");
}
}
}
class SimpleProxyImpl implements SimpleBase
{
public SimpleBase _sBase;
SimpleProxyImpl(SimpleBase sBase)
{
_sBase = sBase;
}
public void myMethod(Integer parm)
{
System.out.println("Do something before invoke");
_sBase.myMethod(parm);
System.out.println("Do something after invoke");
}
}
运行的结果是:
Do something before invoke
it is more than 0
Do something after invoke
在这里,值得注意的是,在SimpleProxyImpl的构造函数中,我们把SimpleTestImpl的实例传输了过来,这样就可以最终调用SimpleTestImpl的MyMethod方法。
那么,进一步,我们还可以实现动态的代理。Jdk1.3提供的Proxy可以使我们更加方便的实现动态代理。所谓动态代理,其实就是根据我们传入的被代理对象,利用反射机制动态的生成被代理的对象的实例,再动态的调用被代理对象的方法。Jdk提供Proxy,需要配合使用实现了InvocationHandler接口的类,事实上实现了InvocationHandler的类就是我们上文所说的代理类。Proxy和InvocationHandler将上述的代理关系进一步规范起来了。下面,让我们看看使用Proxy和InvocationHandler是如何实现代理的。
代码如下:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyTest {
public static void main(String[] args)
{
ProxyClass soapClientProxy = new ProxyClass();
Base obj = (Base) soapClientProxy.get(new BaseImpl());
String s = (String) obj.myMethod(new Integer(-1));
//obj是一个动态匿名类,继承于Proxy,并且实现了Base接口。当Proxy调用具体的一个Method事实上是调用了代理类的invoke的方法。
}
}
class ProxyClass
implements InvocationHandler
{
public Object _handler = null; //我们在这里定义的Object对象存储的是实现了Base接口的类的实例,就是我们的被代理类。
public void setHandler( Object handler ) {
this._handler = handler;
}
public Object get(Object handler){
System.out.println("in get method of MyInvocationHandler");
this._handler = handler;
return Proxy.newProxyInstance(handler.getClass().getClassLoader(),handler.getClass().getInterfaces(),this);
}//这里实现了被代理类B的实例的传入,根据B的实例,生成了继承于Proxy的动态匿名类,在调试过程中,我们可以看到动态代理类的名字以“$Proxy”开头。这个类是实现了Base接口的。
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Class[] params = method.getParameterTypes();
Method realMethod = _handler.getClass().getDeclaredMethod( method.getName(), params );
Object o = realMethod.invoke( _handler, args );
//这里调用了被代理类的相关的method。这个method通过参数传入。在这个invoke的方法总,我们可以同样可以做一些预处理工作和事后处理的工作。
return o;
}
}
interface Base
{
public String myMethod(Integer parm);
}
class BaseImpl implements Base
{
public String myMethod(Integer parm)
{
if (parm > 0)
{
return "It is more than 0";
}
else
{
return "It is equal or less than 0";
}
}
}
总结一下,Jdk1.3提供的Proxy和InvocationHandler就是将代理这种设计模式通过使用Java的一些reflect机制使之规范的起来。它们所做的事情无非还是传入被代理对象的实例,调用被代理对象的方法。
参考文档:
http://dev.firnow.com/course/3_program/java/javajs/20090205/154868.html