简介
JDK动态代理是一种基于JDK自带的Proxy类和InvocationHandler接口的代理方式。它可以在运行时动态地创建一个代理对象,该代理对象可以代替真实对象执行某些操作,从而实现对真实对象的代理。
与Java静态代理相比,JDK动态代理具有更高的灵活性和可扩展性,因为它是基于接口的代理,可以代理任何实现了接口的类。同时,它也更加易于使用,因为不需要手动实现代理类,只需要实现InvocationHandler接口即可。
示例1
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class DynamicProxyExample {
public static void main(String[] args) {
// 创建真实对象
Subject realSubject = new RealSubject();
// 创建代理对象
Subject proxySubject = (Subject) Proxy.newProxyInstance(
realSubject.getClass().getClassLoader(),
realSubject.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 在方法执行前输出日志
System.out.println("Before invoking method: " + method.getName());
// 调用真实对象的方法
Object result = method.invoke(realSubject, args);
// 在方法执行后输出日志
System.out.println("After invoking method: " + method.getName());
// 返回结果
return result;
}
});
// 调用代理对象的方法
proxySubject.request();
}
}
// 定义真实对象的接口
interface Subject {
void request();
}
// 真实对象,实现接口
class RealSubject implements Subject {
@Override
public void request() {
System.out.println("RealSubject: handling request.");
}
}
在上面的代码中,我们创建了一个RealSubject类实现了Subject接口,然后创建了一个代理对象,并通过InvocationHandler实现了对真实对象的代理。在调用代理对象的方法时,会先输出日志,然后调用真实对象的方法,最后再输出日志。这样就可以在方法执行前后进行一些额外的操作,例如记录日志、验证权限等。
运行:
示例2
创建真实对象的接口
public interface SendService {
String send(String message);
}
创建真实对象,实现接口
public class SendServiceImpl implements SendService{
@Override
public String send(String message) {
System.out.println("发送信息:"+message);
return message;
}
}
创建代理类实现InvocationHandler接口
public class MyInvocationHandler implements InvocationHandler {
private final Object target;
public MyInvocationHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//调用方法之前,我们可以添加自己的操作
System.out.println("before method " + method.getName());
Object result = method.invoke(target, args);
//调用方法之后,我们可以添加自己的操作
System.out.println("after method " + method.getName());
return result;
}
}
创建代理工厂,返回代理对象
public class JdkProxyFactory {
public static Object getProxy(Object target) {
return Proxy.newProxyInstance(
target.getClass().getClassLoader(), // 目标类的类加载
target.getClass().getInterfaces(), // 代理需要实现的接口,可指定多个
new MyInvocationHandler(target) // 代理对象对应的自定义 InvocationHandler
);
}
}
主方法,测试动态代理
public class Main {
public static void main(String[] args) {
SendService sendService = new SendServiceImpl();
SendService proxy = (SendService)JdkProxyFactory.getProxy(sendService);
String result = proxy.send("hello world");
}
}
运行: