一、说明
首先,代理就是一个代理对象代表一个目标对象,代理对象往往实现和目标对象一致的接口(动态代理不用,有invoke()函数自动转换),并作为目标对象的代理,接收用户的调用,并将全部或部分调用转发给目标对象。可以看到,代理对象必须实现代理接口和调用转发。代理对象可以在调用转发的前后执行一些功能,也正是这些添加的功能,体现了代理的价值。
动态代理的使用前提是理解java的反射机制。参见http://www.cnblogs.com/rollenholt/archive/2011/09/02/2163758.html
(1)代理接口实现由java.lang.reflect.Proxy类的静态函数
static方法getProxyClass()用于获取代理类的java.lang.Class对象。
static方法newProxyInstance()创建动态代理实例。
(2)调用转发功能由java.lang.reflect.InvocationHandler接口
invoke()是这个接口的唯一方法,当用户调用newProxyInstance()返回的代理对象上的方法时,该代理对象将方法调用转发给调用调用句柄实例,即调用InvocationHandler实例的invoke()方法。
二、代码实现:
首先创建目标类DPQueryStatusImpl:
public interface PDQueryStatus {
DPFileStatus getFileStatus(String filename);
}
public class DPQueryStatusImpl implements PDQueryStatus {
@Override
public DPFileStatus getFileStatus(String filename) {
DPFileStatus status=new DPFileStatus(filename);
System.out.println("Method getFileStatus Called, return: "+status);
return status;
}
}
调用转发:
public class DPInvocationHandler implements InvocationHandler {
private DPQueryStatusImpl dpqs;
public DPInvocationHandler(DPQueryStatusImpl dpqs) {
this.dpqs = dpqs;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Object ret = null;
String msg1 = MessageFormat.format("Calling method {0}({1})",
method.getName(),
Arrays.toString(args));
System.out.println(msg1);
ret = method.invoke(dpqs, args);
String msg2 = MessageFormat.format("Method {0} returned with ({1})",
method.getName(), ret.toString());
System.out.println(msg2);
return ret;
}
}
主类:
public class DPMain {
public static PDQueryStatus create(DPQueryStatusImpl dpqs) {
DPInvocationHandler handler = new DPInvocationHandler(dpqs);
Class<?>[] interfaces=new Class[] { PDQueryStatus.class };
//创建动态代理
Object result = Proxy.newProxyInstance(dpqs.getClass().getClassLoader(),
interfaces,
handler);
Class<?> proxy=Proxy.getProxyClass(dpqs.getClass().getClassLoader(),
interfaces);
System.out.println("Proxy class name: "+proxy.getCanonicalName());
System.out.println("Proxy's super class name: "+proxy.getSuperclass().getName());
System.out.println();
return (PDQueryStatus) result;
}
/**
* @param args
*/
public static void main(String[] args) {
try {
PDQueryStatus query = DPMain.create(new DPQueryStatusImpl());//由目标对象new DPQueryStatusImpl()做参数,返回动态代理对象query
DPFileStatus status = query.getFileStatus("/tmp/testDP");//该调用转变成DPInvocationHandler 的invoke()
System.out.println(status);
} catch (Exception e) {
e.printStackTrace();
}
}
}
运行结果:
Proxy class name: com.sun.proxy.$Proxy0
Proxy's super class name: java.lang.reflect.Proxy
Calling method getFileStatus([/tmp/testDP])
Method getFileStatus Called, return: File: /tmp/testDP Create at Thu May 08 14:50:58 CST 2014
Method getFileStatus returned with (File: /tmp/testDP Create at Thu May 08 14:50:58 CST 2014)
File: /tmp/testDP Create at Thu May 08 14:50:58 CST 2014
/*DPFileStatus定义如下:*/
public class DPFileStatus {
private String filename;
private long time;
public DPFileStatus(String filename) {
this.filename=filename;
this.time=(new Date()).getTime();
}
public String getFilename() {
return filename;
}
public void setFilename(String filename) {
this.filename = filename;
}
public long getTime() {
return time;
}
public void setTime(long time) {
this.time = time;
}
public String toString() {
return "File: "+filename+" Create at "+(new Date(time));
}
}