從JDK1.3以後,Java提供了動態代理的機制。動態代理是一種強大的語言結構,可以爲一個或多個接口創建代理對像而不需要預先用於一個接口的實現類。Java中的動態代理機制可以方便地用於實現AOP。
考慮如下情形:當需要爲多個不具有繼承層次的對象引入同一個公共行爲的時候,例如記錄日誌,安全檢查等等。如果考慮用OOP的思想進行設計,需要爲每一個對象實現相同功能的記錄日誌或者安全檢查的方法,這樣,雖然能解決問題,但是其代價就是在程序中存在大量的重複性代碼。如下圖:
那麼,如何才能更好的解決此問題呢?此時需要用到AOP(面向切面編程)的思想。而利用java中的動態代理機制就能很容易的實現AOP。實現機制如下圖所示:
用java動態代理機制實現的具體步驟如下(以日誌記錄爲例):
1. 創建並編寫接口Log.java
package com.test.proxy;
public interface Log {
public void logging();
}
2. 創建並編寫接口Log.java的實現類LogImpl.java
package com.test.proxy;
public class LogImpl implements Log {
public void logging(){
System.out.println("=====logging方法執行,寫入日誌======");
}
}
3.創建並編寫代理類LogProxy.java。此類實現了java提供的InvocationHandler接口。通過這個代理類,可以在運行是自動創建指定接口的代理對象,並由此代理對象完成相關業務邏輯流程。package com.test.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class LogProxy implements InvocationHandler {
private Object proxyObj;
public LogProxy(Object obj) {
this.proxyObj = obj;
}
@SuppressWarnings("unchecked")
public static Object bind(Object obj) {
Class cls = obj.getClass();
return Proxy.newProxyInstance(cls.getClassLoader(),
cls.getInterfaces(), new LogProxy(obj));
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
dobefore(method);
Object object = method.invoke(proxyObj, args);
doafter(method);
return object;
}
private void dobefore(Method method) {
prt("方法" + method.getName() + "執行前");
}
private void doafter(Method method) {
prt("方法" + method.getName() + "執行後");
}
public void prt(String msg) {
System.out.println(msg);
}
}
4.創建並編寫測試類TestLog.javapackage com.test.proxy.test;
import com.test.proxy.LogProxy;
import com.test.proxy.LogImpl;
import com.test.proxy.Log;
public class Testlog {
public static void main(String[] args) {
// TODO Auto-generated method stub
Log login = (Log)LogProxy.bind(new LogImpl());
login.logging();
}
}
執行後的結構如下:
通過上述步驟,即完成了簡單的java的動態代理。