Dynamic proxies
何为动态代理,java编程思想如是说:
Proxy is one of the basic design patterns.It is an object that you insert in place of the "real" object in order to provide additional or different operations -these usually involve communication with a "real" object,so a proxy typically acts as a go-between.
代理是一个基本的设计模式。是一个对象取代'real'对象来提供一些附加或不同的操作,这通常会涉及到与'real'对象的交互,所以代理可以称为一种媒介。下面是本人近期学习java编程思想4里的代码,与大家分享:
package proxy;
public interface Interface {
void doSomething();
void somethingElse(String arg);
}
package proxy;
public class RealObject implements Interface{
@Override
public void doSomething() {
System.out.println("dosomething");
}
@Override
public void somethingElse(String arg) {
System.out.println("dosomething else");
}
}
package proxy;
public class SimpleProxy implements Interface{
private Interface proxied;
public SimpleProxy(Interface proxied) {
this.proxied = proxied;
}
@Override
public void doSomething() {
System.out.println("dosomething");
proxied.doSomething();
}
@Override
public void somethingElse(String arg) {
System.out.println("dosomething else"+arg);
proxied.somethingElse(arg);
}
}
package proxy;
public class SimpleProxyDemo {
public static void consumer(Interface iface) {
iface.doSomething();
iface.somethingElse(" args");
}
public static void main(String[] args) {
consumer(new RealObject());
consumer(new SimpleProxy(new RealObject()));
}
}
dosomething
dosomething else
dosomething
dosomething
dosomething else args
dosomething else
//以上是代理的模拟实现,下面我们看看java是怎么实现代理的:
package proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* <b>function:</b>
* InvocationHandler 是代理实例的调用处理程序 实现的接口。
* 每个代码实例都具有一个关联的调用处理程序。对代理实例调用方法时,将对方法调用进行编码并将其指派到它的调用处理程序的 invoke 方法。
*
* @author Bruce.Eckel
*/
class DynamicProxyHandler implements InvocationHandler {
private Object proxied;
public DynamicProxyHandler(Object proxied) {
this.proxied = proxied;
}
@Override
/**
* <b>function:</b>在代理实例上处理方法调用并返回结果。在与方法关联的代理实例上调用方法时,将在调用处理程序上调用此方法。
* @parameter
* proxy - 在其上调用方法的代理实例
* method - 对应于在代理实例上调用的接口方法的 Method 实例。Method 对象的声明类将是在其中声明方法的接口,该接口可以是代理类赖以继承方法的代理接口的超接口。
* args - 包含传入代理实例上方法调用的参数值的对象数组,如果接口方法不使用参数,则为 null。基本类型的参数被包装在适当基本包装器类(如 java.lang.Integer 或 java.lang.Boolean)的实例中。
*
*/
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("**** proxy: "+proxy.getClass()+
", method: "+method+" ,args: "+args);
if(args != null) {
for(Object arg : args) {
System.out.println(arg);
}
return method.invoke(proxied, args);//对带有指定参数的指定对象调用由此 Method 对象表示的基础方法。
}
return null;
}
}
class SimpleDynamicProxy {
public static void consumer(Interface iface) {
iface.doSomething();
iface.somethingElse(" args");
}
public static void main(String[] args) {
RealObject real = new RealObject();
consumer(real);
Interface proxy = (Interface)Proxy.newProxyInstance(
Interface.class.getClassLoader(),
new Class[]{Interface.class},
new DynamicProxyHandler(real));
/** 另一种写法
InvocationHandler handler = new DynamicProxyHandler(real);
Class proxyClass = Proxy.getProxyClass(
Interface.class.getClassLoader(), new Class[] { Interface.class });
Interface proxy = (Interface)proxyClass.
getConstructor(new Class[] { InvocationHandler.class }).
newInstance(new Object[] { handler });
*/
consumer(proxy);
}
}
dosomething
dosomething else
**** proxy: class $Proxy0, method: public abstract void proxy.Interface.doSomething() ,args: null
**** proxy: class $Proxy0, method: public abstract void proxy.Interface.somethingElse(java.lang.String) ,args: [Ljava.lang.Object;@47b480
args
dosomething else