接口
package org.leo.proxy;
/**
* @author Leo.Chen
*/
public interface XiangQin {
String xiangQin(String guNiang);
}
针对接口的某种具体实现
package org.leo.proxy;
/**
* realSubject
*/
public class LeoXiangQin implements XiangQin {
@Override
public String xiangQin(String guNiang) {
System.out.println("Leo 和 " + guNiang + " 去相亲了。");
return "successed! ";
}
}
实现JDK定义的处理动态代理整个过程的接口
/**
*
*/
package org.leo.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
* @author Leo.Chen
*
*/
public class XiangQinInvocationHandler implements InvocationHandler {
private XiangQin xiangQin;
public XiangQinInvocationHandler(final XiangQin xiangQin) {
super();
this.xiangQin = xiangQin;
}
/**
* proxy : com.sun.proxy.$Proxy0 代理类
* method: 接口中定义的方法对象
* args: 接口方法入参
* Object: 方法调用返回结果
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {
doBefore();
/*proxy 是代理对象$Proxy0 extends Proxy implements XiangQin的类,
* 如果proxy cast为XiangQin,
* 然后执行接口method,将会出现死循环
*/
/**
* 为什么出现死循环?
* 动态代理类$Proxy0调用execute方法时会调用$Proxy0它自己的xiangQin方法
* 而它自己的execute方法里面调用的是super.h.invoke(this,method,args),
* 也就是父类Proxy的h(InvocationHandler)的invoke方法,
* 即XiangQinInvocationHandler的invoke方法,方法中不断的重复调用自己
*/
/*((XiangQin)proxy).execute("美女");*/
System.out.println("proxy:"+proxy.getClass().getCanonicalName());
System.out.println("method:"+method.getName()+",returnType:"+method.getReturnType().getCanonicalName());
/*result为方法调用返回结果*/
Object result = method.invoke(xiangQin, args);
System.out.println("result's type :"+result.getClass().getCanonicalName());
doAfter();
return result;
}
protected void doBefore(){
System.out.println("before:相亲之前打扮自己。");
}
protected void doAfter(){
System.out.println("after:相亲成功了。");
}
}
代理工具类
package org.leo.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
public class ProxyXiangQin {
public static void main(String[] args) {
/**
* 在java种怎样实现动态代理呢
* 第一步,我们要有一个接口,还要有一个接口的实现类,而这个实现类呢就是我们要代理的对象,
* 所谓代理呢也就是在调用实现类的方法时,可以在方法执行前后做额外的工作,这个就是代理。
* 第二步,我们要自己写一个在要代理类的方法执行的前后可以做额外工作的类,而这个类必须继承InvocationHandler接口,
* 为什么要继承它呢?因为代理类的实例在调用实现类的方法的时候,不会调真正的实现类的这个方法,
* 而是转而调用这个类的invoke方法(继承时必须实现的方法),在这个方法中你可以调用真正的实现类的这个方法。
* 第三步,在要用代理类的实例去调用实现类的方法的时候,写出下面两段代码。
*/
XiangQin qin = new LeoXiangQin();
InvocationHandler handler = new XiangQinInvocationHandler(qin);
XiangQin proxy = (XiangQin) Proxy.newProxyInstance(qin.getClass().getClassLoader(), qin.getClass().getInterfaces(), handler);
String result = proxy.execute("美女");
System.out.println("result:"+result);
}