JDK提供了动态代理功能,主要是应用反射功能来实现,在java.lang.reflect包中,有Proxy类和InvocationHandler接口。JDK动态代理只能代理接口,无法代理类,动态代理类在Spring中是用的CGLib,这里只研究JDK的动态代理。
既然是动态代理接口,首先要新建接口:
package dynProxy;
public interface Sleep {
public void sleep();
}
实现此接口的类:
package dynProxy;
public class RealSleep implements Sleep{
@Override
public void sleep() {
// TODO Auto-generated method stub
System.out.println("time to sleep");
}
}
其次就是开始真正的动态代理,要实现InvocationHandler接口:
package dynProxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyHandle implements InvocationHandler{
private Object obj;
public Object bind(Object obj){
this.obj=obj;
//Proxy有一个方法newProxyInstace();有三个参数:第一个:表示所代理的真实类类的实例的类的加载器
//第二个参数表示是:所要代理的真实类所实现的接口
//第三个是:代理类本身
return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
//调用参数method中的invoke()方法,其中有两个参数
//第一个参数表示:代理的真实类
//第二个参数表示:传入的参数 对象数组
System.out.println("Before sleep:Take off clothes!");
Object o = method.invoke(this.obj, args);
System.out.println("After sleep:Have a good dream!");
return o;//返回一个所代理的接口的实现类
}
}
最后就是测试类了:
package dynProxy;
public class DynProxtTest {
public static void main(String[] args){
ProxyHandle han=new ProxyHandle();
Sleep sleep=(Sleep)han.bind(new RealSleep());
sleep.sleep();
}
}
测试的结果正是我们想要的:
Before sleep:Take off clothes!
time to sleep
After sleep:Have a good dream!