// 介面
public interface Hello { void say(String msg); }
// 真實物件
public class HelloImpl implements Hello {
public void say(String msg) { System.out.println("Hi, " + msg); }
}
// 代理物件(實作相同介面)
public class HelloProxy implements Hello {
private Hello target;
public HelloProxy(Hello target) { this.target = target; }
public void say(String msg) {
before();
target.say(msg);
after();
}
private void before() { System.out.println("Before"); }
private void after() { System.out.println("After"); }
}
public class HelloTarget {
public void sayHello(String name) { System.out.println("Hi, " + name); }
}
public class HelloProxy extends HelloTarget {
private HelloTarget target;
public HelloProxy(HelloTarget target) { this.target = target; }
@Override
public void sayHello(String name) {
before();
target.sayHello(name);
after();
}
// before/after 同前
}
HelloImpl target = new HelloImpl();
Hello proxy = (Hello) Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("before");
Object ret = method.invoke(target, args); // 反射調用目標方法
System.out.println("after");
return ret;
}
}
);
proxy.say("LZHL");
Proxy.newProxyInstance(loader, interfaces, handler)InvocationHandler.invoke(proxy, method, args):攔截所有方法調用目標類必須實作至少一個介面,否則無法使用 JDK 動態代理。
需引入依賴:
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.2.4</version>
</dependency>
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(Hi.class); // 目標類無需實作介面
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
System.out.println("before");
Object ret = proxy.invokeSuper(obj, args); // 調用父類方法
System.out.println("after");
return ret;
}
});
Hi proxy = (Hi) enhancer.create();
proxy.sayHi("LXY");
| 項目 | JDK 動態代理 | CGLIB 動態代理 |
|---|---|---|
| 機制 | 實作介面 | 繼承目標類 |
| 目標類要求 | 必須實作介面 | 無要求(非 final 類) |
| 核心類 | Proxy + InvocationHandler | Enhancer + MethodInterceptor |
| 調用方式 | method.invoke(target, args) | proxy.invokeSuper(obj, args) |
| final 方法 | 可代理 | 無法代理 |
proxy-target-class=true 全用 CGLIB)