給目標(biāo)對象提供一個代理對象,并由代理對象控制對目標(biāo)對象的引用。
靜態(tài)代理

image.png
package proxy;
public interface Subject {
void doSomthing();
}
package proxy;
public class RealSubject implements Subject{
@Override
public void doSomthing() {
System.out.println("I need do some things");
}
}
package proxy;
public class ProxySubject implements Subject {
private Subject subject;
@Override
public void doSomthing() {
subject = new RealSubject();
subject.doSomthing();
}
}
動態(tài)代理
動態(tài)代理相關(guān)API
| API | 用途 |
|---|---|
Proxy#newProxyInstance |
創(chuàng)建一個代理 |
InvocationHandler#invoke |
用于處理動態(tài)代理類對對象的方法調(diào)用 |
如何創(chuàng)建動態(tài)代理
第一步,實現(xiàn)InvocationHandler接口,并重寫invoke方法。在invoke方法中處理代理類中需要處理的邏輯。
package proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class DynamicProxyHandler implements InvocationHandler {
Object proxied;
public DynamicProxyHandler(Object proxied){
this.proxied = proxied;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("method="+method+" proxy="+proxy.getClass());
if (args != null) {
for (Object arg: args) {
System.out.println("arg="+arg);
}
}
return method.invoke(proxied, args);
}
}
第二步,使用Proxy#newProxyInstance創(chuàng)建代理對象。newProxyInstance方法的參數(shù)分別為:
- ClassLoader loader:指定當(dāng)前目標(biāo)對象使用類加載器,用null表示默認(rèn)類加載器
- Class [] interfaces:需要實現(xiàn)的接口數(shù)組
- InvocationHandler handler:調(diào)用處理器,執(zhí)行目標(biāo)對象的方法時,會觸發(fā)調(diào)用處理器的方法,從而把當(dāng)前執(zhí)行目標(biāo)對象的方法作為參數(shù)傳入
package proxy;
import java.lang.reflect.Proxy;
public class Test {
public static void main(String[] args) {
// 動態(tài)代理
Subject real = new RealSubject();
Subject proxy = (Subject) Proxy.newProxyInstance(Subject.class.getClassLoader(),
new Class[]{Subject.class}, new DynamicProxyHandler(real));
proxy.doSomthing();
}
}
動態(tài)代理特點
- 不需要手動創(chuàng)建代理類,它會在運行期,通過反射機制創(chuàng)建一個實現(xiàn)了一組給定接口的新類
- 必須要實現(xiàn)InvocationHandler接口
- 接口中聲明的所有方法都被轉(zhuǎn)移到調(diào)用處理器一個集中的方法中處理(InvocationHandler.invoke)。