JDK动态代理的前提是必须有接口,JDK 动态代理会为每个业务接口动态生成相应的代理类实现,并加载到 JVM 中,然后创建对应的代理实例对象。
JDK 动态代理的实现原理:动态创建代理类,然后通过指定类加载器进行加载。
1) JDK动态代理的核心是InvocationHandler接口,该接口只包含一个抽象方法
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable;
参数说明:
Object proxy — 被代理的对象
Method method — 被代理的方法
Object[] args — 被代理方法的参数数组
2)Proxy类
该类包含代理相关的静态方法,最常用的是生成代理对象
public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)
参数说明:
loader(ClassLoader 类型):加载动态生成的代理类的类加载器。
interfaces(Class[] 类型):业务类实现的接口。
h(InvocationHandler 类型):自定义的 InvocationHandler 对象。
该方法的功能如下:
1).生成一个实现了参数interfaces里所有接口且继承了Proxy的代理类的字节码,然后用参数里的classLoader加载这个代理类。
2).使用代理类父类的构造函数 Proxy(InvocationHandler h)来创造一个代理类的实例,将我们自定义的InvocationHandler的子类传入。
3).返回这个代理类实例。
示例:
目标接口
public interface Subject {
void sayHello();
}
目标类:
public class RealSubject implements Subject{
@Override
public void sayHello() {
System.out.println("hello, I am RealSubject");
}
}
用于生成JDK代理的类
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class JDKProxy implements InvocationHandler {
private Object target; // 真正的业务对象,需要代理的目标对象
// DemoInvokerHandler构造方法
public JDKProxy(Object target) {
this.target = target;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("before do..."); // 在执行业务逻辑之前的预处理逻辑
Object result = method.invoke(target, args);
System.out.println("after do..."); // 在执行业务逻辑之后的后置处理逻辑
return result;
}
public Object getProxy() { //获取代理对象
// 创建代理对象
return Proxy.newProxyInstance(Thread.currentThread()
.getContextClassLoader(),
target.getClass().getInterfaces(), this);
}
}
测试
public class Test {
public static void main(String[] args) {
Subject subjectProxy = (Subject)new JDKProxy(new RealSubject()).getProxy();
subjectProxy.sayHello();
}
}