動態代理
為了避免撰寫大量重複的代理code,在JDK 1.3以後開始支援動態代理。
關鍵就是Proxy.newProxyInstance()
這個方法
範例
動態代理,必須實作InvocationHandler
的invoke()
方法
在invoke()
裡,定義您想代理的內容,本例就是實作記錄log
class LogProxy implements InvocationHandler {
Object subject;
public Object getLogProxy(Object subject) {
this.subject = subject;
return Proxy.newProxyInstance(
subject.getClass().getClassLoader(),
subject.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Exception {
System.out.println("dynamic proxy method starts ..." + method);
Object result = method.invoke(subject, args);
System.out.println("dynamic proxy method ends." + method);
return result;
}
}
使用者也和proxy
蠻類似的
把要代理的subject
送到LogProxy
裡,最後呼叫hello()
即可
interface IHello {
public void hello(String name);
}
class HelloSpeaker implements IHello {
public void hello(String name) {
System.out.println("hello " + name);
}
}
IHello speaker = (IHello) new LogProxy().getLogProxy(new HelloSpeaker());
speaker.hello("welson");
AOP
剛剛的例子和AOP(Aspect Orient Programing)有什麼關呢?
業務邏輯(記錄log,權限檢查,...)經常出現在程式每個地方,在AOP的術語稱為cross-cutting
LogProxy因為代理模式的關係,讓商業邏輯與業務邏輯分離
如果沒有代理,則HelloSpeaker
必定職責加重
於此,LogProxy就是AOP的Aspect,中譯為「切面」(中譯不太重要)
請參考AOP一節。