上篇介紹了靜態代理模式
https://blog.csdn.net/liufangbaishi2014/article/details/90673154
在看本文之前,讀者最好,先瀏覽一下
既然已經有了靜態代理模式,爲什麼還要有動態代理模式呢?
那我們先來談下靜態代理模式的侷限性:
1.一個代理類只能代理一類(實現了特定接口的)對象;
2.一個代理類只能代理一個(特定接口的)方法;
就像是我們想要賣房子,既需要找一個代理,幫我們把房子賣了,同時,還需要找另外一個代理,幫我們把傢俱賣了。我能不能直接找個萬能的代理,直接把這兩件事兒,甚至是n件事(比如還要賣車)一起辦了呢?
動態代理模式可以辦到。通過proxy產生某一個類(需要實現某個接口)的代理對象,幫該類做一些操作。最終,該類所有的類的方法在執行之前,都會先執行代理對象的invoke方法,並把原方法的名稱和參數傳入。樣例代碼如下:
package anjz.anjz;
import org.objectweb.asm.commons.GeneratorAdapter;
public interface Test {
void dosomesthing();
}
package anjz.anjz;
public class TestImpl implements Test{
public void dosomesthing() {
System.out.println("被代理的類做的事情");
}
}
package anjz.anjz;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class TestInterface implements InvocationHandler{
private Object target=null;//保存真實業務對象
/**
* 返回動態代理類的對象,這樣用戶纔可以利用代理類對象去操作真實對象
* @param obj 包含有真實業務實現的對象
* @return 返回代理對象
*/
public Object getProxy(Object obj) {
this.target=obj;//保存真實業務對象
return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj
.getClass().getInterfaces(), this);
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//自定義邏輯
System.out.println("方法前邊 -自定義邏輯");
method.invoke(target, args);
//自定義邏輯
System.out.println("方法後邊 -自定義邏輯");
return null;
}
public static void main(String[] args) {
TestImpl tImpl = new TestImpl();
TestInterface tInterface = new TestInterface();//新建代理對象,代理對象中有對方法的攔截和處理邏輯
Test test= (Test)tInterface.getProxy(tImpl);//產生一個和tImpl對象實現了同一個接口的代理類
test.dosomesthing();
}
}
這裏面用到了類Proxy,用來通過調用newProxyInstance方法產生代理對象;
一個InvocationHandler接口,用來攔截目標類對方方法,以插入代理邏輯。
講到這裏大家有沒有發現一個問題,代理在做的事情,就是AOP所做的事情,就是攔截目前方法,插入我們想要的邏輯。
你想的沒錯,Spring的AOP就是這麼實現的。只不過Spring將AOP配置化了,可以通過xml的配置或者註解完成,但是最後的實現思路,還是上邊的這套邏輯。
Spring AOP編程在我的實際應用中,除了特定的幾個場景(權限控制、日誌打印),用的並不是特別多。而他在某一方面的應用卻十分常見,就是事物管理。
spring通過在數據庫操作前後插入事物回滾邏輯,就可以進行事物管理。我們在日常編程中,一般是定義一些通用方法,只要以這些方法開頭的如update 、insert開頭的方法,都進行事物管理。
參考文檔:
https://www.jianshu.com/p/fc285d669bc5
歡迎留言交流