Java 提供 java.lang.reflect.Proxy 和 InvocationHandler 實現動態代理。代理類在運行時生成,實現指定接口,將方法調用分發給 InvocationHandler.invoke(),實現 AOP、遠程調用、事務管理等橫切關注點分離。
invoke(Object proxy, Method method, Object[] args),處理代理方法調用。newProxyInstance(ClassLoader, Class[] interfaces, InvocationHandler) 創建代理實例。// 1. 定義業務接口
public interface Subject {
void request();
}
// 2. 真實主題
public class RealSubject implements Subject {
@Override public void request() { System.out.println("真實業務邏輯執行"); }
}
// 3. 代理處理器:攔截並增強
public class LoggingHandler implements InvocationHandler {
private final Object target; // 被代理對象
public LoggingHandler(Object target) { this.target = target; }
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("【前置】調用方法: " + method.getName());
long start = System.currentTimeMillis();
Object result = method.invoke(target, args); // 反射調用真實方法
System.out.println("【後置】耗時: " + (System.currentTimeMillis() - start) + "ms");
return result;
}
}
// 4. 客戶端
public class Client {
public static void main(String[] args) {
RealSubject real = new RealSubject();
InvocationHandler handler = new LoggingHandler(real);
// 生成代理實例
Subject proxy = (Subject) Proxy.newProxyInstance(
real.getClass().getClassLoader(),
real.getClass().getInterfaces(),
handler
);
proxy.request(); // 觸發攔截
}
}
public class ProxyFactory {
@SuppressWarnings("unchecked")
public static T createProxy(T target, InvocationHandler handler) {
return (T) Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
handler
);
}
}
// 使用
Subject proxy = ProxyFactory.createProxy(new RealSubject(), new LoggingHandler(real));
public class VectorProxy implements InvocationHandler {
private final Object target;
private VectorProxy(Object target) { this.target = target; }
public static List newInstance() {
return (List) Proxy.newProxyInstance(
Vector.class.getClassLoader(),
new Class[]{List.class},
new VectorProxy(new Vector<>())
);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("呼叫: " + method.getName() + " 參數: " + Arrays.toString(args));
return method.invoke(target, args);
}
}
// 測試
List list = VectorProxy.newInstance();
list.add("A");
list.add("B");
System.out.println(list); // 觸發 toString() 也會被攔截
Proxy,實現目標接口。無法代理普通類(需用 CGLIB/ByteBuddy 繼承子類代理)。Proxy 生成的代理類中 final 方法直接調用父類實現,不走 invoke。Serializable,但序列化後反序列化需相同 ClassLoader 環境。Spring AOP、RPC 框架(Dubbo、gRPC Java)、MyBatis Mapper 動態實現、事務管理、權限檢查、緩存、日誌監控等。