什麼是代理?
所謂代理呢也就是在調用實作類別的方法時,可以在方法執行前後做額外的工作,這個就是代理。
那動態代理呢,官方解釋是:
Java 動態代理機制的出現,使得 Java 開發人員不用手工編寫代理類,只要簡單地指定一組介面及委託類對象,便能動態地獲得代理類。代理類會負責將所有的方法調用指派到委派物件上反射執行,在指派執行的過程中,開發人員還可以按需調整委託類對象及其功能,這是一套非常靈活有彈性的代理架構。
我更喜歡另一種通俗的解釋,官方的解釋總是高度抽象的,等用了一段時間才能理解體會
動態代理實現了日誌和業務的分開,也就是某個類只是要提供了某些業務,比如銀行取款業務。這個類實現了取款業務的同時也需要實現日誌功能,如果不用動態代理的話,那麼由此一來該類代碼裡面已經額外地添加了自己不該添加的日誌功能能代碼。所以我們就得使用動態代理把它的業務代碼和日誌功能代碼分開。所以用到了動態代理概念,spring裡面的AOP就是一個很好的例子。
這樣的話,我們來看一個例子,要用到的兩個類
實現java.lang.reflect.InvocationHandler介面提供一個執行處理器,也就是真正做事的,然後通過java.lang.reflect.Proxy得到一個代理對象,通過這個代理對象來執行業務方法,在業務方法被調用的同時,執行處理器會被自動調用。 記住,動態代理只能對介面
首先業務介面:
public interface HelloWorld {
public void sayHelloWorld();
}
然後我們是這樣寫的實現
public class HelloWorldImpl implements HelloWorld {
public void sayHelloWorld() {
System.out.println(“Hello World!”);
}
}
後來我們覺得執行這個方法前能不能做點其他啥事呢,比如寫個日誌?見個妹子?啥,這段代碼不讓改了,改了的話,業務方法和日誌混合的一塌糊塗啊,以後想改個日誌格式你來寫啊
那我們就得定義一個攔截器/執行處理器了。
public class HelloWorldHandler implements InvocationHandler {
//目標對象
private Object targetObject;
public HelloWorldHandler(Object targetObject){
this.targetObject = targetObject;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println(“方法調用前”);
Object result = method.invoke(this.targetObject, args);
System.out.println(“方法調用結束”);
return result;
}
}
這用戶端咋用啊
public class HelloWorldTest {
public static void main(String[] args) {
//業務對象
HelloWorld obj = new HelloWorldImpl();
//攔截器對象
HelloWorldHandler handler = new HelloWorldHandler(obj);
//返回業務對象的代理對象
HelloWorld proxy = (HelloWorld)Proxy.newProxyInstance(
obj.getClass().getClassLoader(),
obj.getClass().getInterfaces(),
handler);
//通過代理對象執行業務對象的方法
proxy.sayHelloWorld();
}
}
看到沒,通過Proxy類的newProxyInstance方法,傳入類載入器,類介面,和這個處理器,我們就獲得一個代理
執行結果是這樣的
方法調用前
Hello World!
方法調用結束
恩,電腦沒死機,是這樣的