Java JDK动态代理只能基于接口实现
目标接口
public interface TargetInterface {
public void sayHi();
public void work();
}
目标接口实现类
public class TargetInterfaceImpl implements TargetInterface {
@Override
public void sayHi() {
System.out.println("Hi,dynamic proxy.sayHi ");
}
@Override
public void work() {
System.out.println("Hi,dynamic proxy.work ");
}
}
目标接口 JDK动态代理类
/**
* author:qxstart
* 实现jdk提供的invocationHandler接口
* 实现该接口是为了实现jdk的动态代理
* 此类不是真正的代理类,真正的代理类在jvm内存中,我们看不见摸不着,这个真正的代理类名字一般是以$Proxy
*/
public class TargetProxy implements InvocationHandler {
// 持有目标接口的引用,动态代理为了适配各种目标类型,把引用使用 Object
private Object target;
/**
* 使用构造方法对目标接口的引用实现初始化
*
* @param target
*/
public TargetProxy(Object target) {
this.target = target;
}
/**
* 获取真正的代理类
*
* @param interfaces
* @param <T>
* @return
*/
// /unchecked/
public <T> T getProxy(Class interfaces) {
// 1 jvm内存中生成一个 class 类
// 2 根据该 class 类反射创建一个代理对象 $Proxy@65432
return (T) Proxy.newProxyInstance(interfaces.getClassLoader(), new Class[]{interfaces}, this);
}
/**
* 覆盖InvocationHandler接口的方法
* 该方法会对目标接口的方法进行拦截
*
* @param proxy 这个就是我们的代理类,就是jdk生成的那个叫$Proxy 代理类
* @param method 就是目标接口的方法,比如 sayHi() ,work() 的反射对象Method
* @param args 就是目标接口的方法,比如 sayHi(),work() 的参数
* @return
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("前置增强(通知)......");
// 中间是调用目标接口的方法
Object result = method.invoke(target, args);
System.out.println("后置增强(通知)......");
return result;
}
}
测试类
public class Client_2 {
public static void main(String[] args) {
//使用动态代理
// System.setProperty("sun.misc.ProxyGenerator.saveGeneratedFiles","true"); //true 可保存代理对象文件到本地磁盘
//获取代理类(这还不是真正的代理对象)
TargetProxy proxyClass = new TargetProxy(new TargetInterfaceImpl());
//真正的代理对象 $Proxy65312
TargetInterface targetClass = (TargetInterface)proxyClass.getProxy(TargetInterface.class);
targetClass.sayHi(); //$Proxy65312 的super.h.invoke(this,m3,(object[])null);
System.out.println("-------------------------");
targetClass.work();
}
}
输出结果