Java动态代理模式怎么实现
动态代理是指在运行期间通过反射机制动态地生成代理类,从而实现对目标对象的调用;而静态代理则是在编译期间就已经生成好代理类,因此无法灵活地处理各种代理需求。
Java中的动态代理主要有两种实现方式:基于接口的动态代理和基于类的动态代理。
基于接口的动态代理
基于接口的动态代理主要利用Java的反射机制,实现动态创建符合指定接口的代理对象。
以下是基于接口的动态代理的实现步骤:
1. 创建InvocationHandler接口的实现类,该类负责实现invoke方法,在该方法中对目标方法进行增强处理。
2. 使用Proxy类的newProxyInstance方法创建代理对象。该方法有三个参数:ClassLoader loader、Class[] interfaces、InvocationHandler h。其中,ClassLoader loader一般指定目标对象的类加载器,Class[] interfaces指定目标对象所实现的接口,InvocationHandler h指定代理对象的业务处理逻辑。
下面是一个基于接口的动态代理实例:
public interface Subject {
void request();
}
public class RealSubject implements Subject {
public void request() {
System.out.println("RealSubject's request method.");
}
}
public class DynamicProxy implements InvocationHandler {
private Object subject;
public DynamicProxy(Object subject) {
this.subject = subject;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("before");
method.invoke(subject, args);
System.out.println("after");
return null;
}
}
public class Client {
public static void main(String[] args) {
RealSubject rs = new RealSubject();
InvocationHandler ih = new DynamicProxy(rs);
ClassLoader cl = rs.getClass().getClassLoader();
Subject subject = (Subject) Proxy.newProxyInstance(cl, rs.getClass().getInterfaces(), ih);
subject.request();
}
}
在该例子中,RealSubject是被代理的类,DynamicProxy是InvocationHandler的实现类,Client类是测试类。
基于类的动态代理
基于类的动态代理主要利用字节码生成技术,在运行期间动态创建代理类。
以下是基于类的动态代理的实现步骤:
1. 创建一个继承自Proxy的代理类,并重写其中的invoke方法,在该方法中对目标方法进行增强处理。
2. 使用字节码生成技术生成代理类的字节码,最后通过类加载器加载该字节码并生成代理对象。
下面是一个基于类的动态代理实例:
public class DynamicProxy extends Proxy {
protected DynamicProxy(InvocationHandler h) {
super(h);
}
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException {
try {
// 生成代理类的字节码
byte[] proxyClassFile = ProxyGenerator.generateProxyClass("$Proxy0", interfaces);
// 将字节码写入到文件中,可以查看生成的代理类的结构信息
FileOutputStream out = new FileOutputStream("./$Proxy0.class");
out.write(proxyClassFile);
out.flush();
out.close();
// 加载代理类字节码并生成代理对象
Class<?> proxyClass = defineClass(loader, proxyClassFile, 0, proxyClassFile.length);
return proxyClass.getConstructor(InvocationHandler.class).newInstance(h);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
public class RealSubject {
public void request() {
System.out.println("RealSubject's request method.");
}
}
public class DynamicProxyTest {
public static void main(String[] args) {
InvocationHandler ih = new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("before");
Object result = method.invoke(new RealSubject(), args);
System.out.println("after");
return result;
}
};
RealSubject subject = (RealSubject) DynamicProxy.newProxyInstance(DynamicProxyTest.class.getClassLoader(), new Class[]{RealSubject.class}, ih);
subject.request();
}
}
在该例子中,RealSubject是被代理的类,DynamicProxy是代理类的实现类,DynamicProxyTest是测试类。通过代理类的字节码生成技术,动态生成代理类,并通过类加载器加载代理类,并最终生成代理对象。
