1. 簡介
代理模式屬於設計模式中的結構型模式,有靜態代理和動態代理兩種實現方式。代理模式使用代理類來控制訪問委託類中方法或者增強委託類的功能。
2. 實現
靜態代理
靜態代理即是代理類在編譯期間已知。
UML類圖
如上圖所示:Subject
介面定義了代理類Proxy
和委託類RealSubject
共同的方法request()
RealSubject
委託類,它是被代理和控制訪問的物件Proxy
代理類引用了RealSubject
的物件,實現了對它的訪問控制
程式碼實現
interface Subject{
void request();
}
class RealSubject implements Subject{
@Override
public void request() {
System.out.println("request");
}
public void run(){
System.out.println("run");
}
}
class Proxy implements Subject{
private Subject subject;
public Proxy(Subject subject){
this.subject = subject;
}
@Override
public void request() {
System.out.println("before");
subject.request();
System.out.println("after");
}
}
複製程式碼
動態代理
動態代理即是代理類在執行期間產生,這個需要用到Java的反射機制,使用JDK的java.lang.reflect
這個包中的一個介面和類:
InvocationHandler
介面是個呼叫處理器,通過重寫invoke(Object proxy, Method method, Object[] args)
方法來對委託類中的方法進行控制訪問。Proxy
類提供幾個靜態方法:getProxyClass(ClassLoader loader, Class<?>... interfaces)
方法通過傳入類載入器和委託類實現的介面這些引數來生成一個代理類,生成的代理類繼承了Proxy
並且實現了所有委託類的介面newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
方法建立一個代理類例項
程式碼實現
interface Subject{
void request();
}
/委託類
class RealSubject implements Subject {
@Override
public void request() {
System.out.println("request");
}
public void run(){
System.out.println("run");
}
}
/呼叫處理器
class ProxyInvocationHandler implements InvocationHandler{
private Object realSubject;
public ProxyInvocationHandler(Object realSubject){
this.realSubject = realSubject;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("before");
Object returnObject = method.invoke(realSubject, args);
System.out.println("after");
return returnObject;
}
}
class ProxyClass {
private Class<?> proxy;
private ProxyInvocationHandler handler;
private Object realSubject;
public ProxyClass(ProxyInvocationHandler handler, Object realSubject) {
this.handler = handler;
this.realSubject = realSubject;
this.proxy = productProxyClass();
}
/產生代理類
private Class<?> productProxyClass() {
ClassLoader loader = ClassLoader.getSystemClassLoader();
Class<?>[] interfaces = realSubject.getClass().getInterfaces();
return Proxy.getProxyClass(loader, interfaces);
}
public Class<?> getProxy() {
return proxy;
}
/建立代理類物件
public Object newInstance() {
try {
Constructor constructor = proxy.getDeclaredConstructor(InvocationHandler.class);
return constructor.newInstance(handler);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return null;
}
}
public class DynamicProxy{
public static void main(String[] args){
/建立委託類物件
Subject realSubject = new RealSubject();
/建立代理類呼叫處理器
ProxyInvocationHandler handler = new ProxyInvocationHandler(realSubject);
ProxyClass proxyClass = new ProxyClass(handler, realSubject);
生成代理類物件
Subject proxy = (Subject) proxyClass.newInstance();
proxy.request();
}
}
複製程式碼