在Java中,代理模式是一种常用的设计模式,用于为其他对象提供一种代理以控制对这个对象的访问。代理模式主要分为静态代理和动态代理两种。
### 静态代理
静态代理是在程序编译时期就已经确定的代理类。代理类与被代理类实现同一个接口(或被代理类继承自同一个父类),在代理类中通过调用被代理类的方法来执行具体的操作,同时可以在调用前后添加自定义的逻辑。
**示例代码**(假设有一个接口`Subject`和两个实现类`RealSubject`、`StaticProxy`):
interface Subject {
void request();
}
class RealSubject implements Subject {
@Override
public void request() {
System.out.println("Executing real request.");
}
}
class StaticProxy implements Subject {
private Subject realSubject;
public StaticProxy(Subject realSubject) {
this.realSubject = realSubject;
}
@Override
public void request() {
preRequest();
realSubject.request();
postRequest();
}
private void preRequest() {
System.out.println("Before real request.");
}
private void postRequest() {
System.out.println("After real request.");
}
}
// 使用
public class ProxyPatternDemo {
public static void main(String[] args) {
Subject realSubject = new RealSubject();
Subject proxy = new StaticProxy(realSubject);
proxy.request();
}
}
### 动态代理
动态代理是在程序运行时动态生成的代理类。它主要利用了Java的反射(Reflection)机制,在运行时动态地创建代理类的字节码,并加载到JVM中。Java的动态代理通常是通过`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口来实现的。
**示例代码**(使用JDK动态代理):
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
interface Subject {
void request();
}
class RealSubject implements Subject {
@Override
public void request() {
System.out.println("Executing real request.");
}
}
class DynamicProxyHandler implements InvocationHandler {
private Object subject;
public DynamicProxyHandler(Object subject) {
this.subject = subject;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
preRequest();
Object result = method.invoke(subject, args);
postRequest();
return result;
}
private void preRequest() {
System.out.println("Before real request.");
}
private void postRequest() {
System.out.println("After real request.");
}
@SuppressWarnings("unchecked")
public static <T> T getProxyInstance(T subject) {
return (T) Proxy.newProxyInstance(
subject.getClass().getClassLoader(),
subject.getClass().getInterfaces(),
new DynamicProxyHandler(subject)
);
}
}
// 使用
public class ProxyPatternDemo {
public static void main(String[] args) {
Subject realSubject = new RealSubject();
Subject proxy = DynamicProxyHandler.getProxyInstance(realSubject);
proxy.request();
}
}
在上面的动态代理示例中,`DynamicProxyHandler`类实现了`InvocationHandler`接口,并通过`Proxy.newProxyInstance`方法创建了代理类的实例。这个代理类在运行时动态生成,并且实现了与`RealSubject`相同的接口`Subject`。当调用代理类的`request`方法时,实际上会调用`DynamicProxyHandler`的`invoke`方法,从而实现了在调用前后添加自定义逻辑的功能。