阿里雲大學JavaWeb開發系列課程:Spring框架入門第十六講回顧

aop的本質就是動態代理

使用靜態代理設計模式的原因:在傳統的業務層,我們需要加上很多的公共業務或稱之爲關注點,比較常見的就是日誌,安全,權限,緩存,事務等等。如果我們把這些公共業務放到每個方法中,會發現方法中都是重複的代碼。本着代碼重用的原則,我們把這些重複的代碼放到一個公共的方法中去。但由於這些公共的業務不僅是一個業務類要去實現,可能會有很多個,甚至是整個項目中的絕大部分,像增刪改查都需要事務的管理。對於這樣的情況,更多的是想把它提到一個類中來做,通過類來調用使得它可以重用。但是即使用類來調用,比如說在每個類中寫log()方法,然後A.log()去調用它,在業務的方法中至少會有一個調用的代碼,這個調用的代碼和業務本身沒有什麼關係,只是我們在執行這個方法時需要用到的附加功能。這樣會使得業務不是很純粹。而且還有了依賴的關係。

領域業務—領域模型

不同的行業涉及到的領域不同,但都會涉及到共同的業務,我們把這些業務抽出來,就成了領域模型,按照這個模型去進行操作。

比如做一個支付的業務(支付模型),要採用第三方去支付,首先接入第三方的接口,在第三方接口中會進行安全檢測,身份驗證,資金驗證,然後才完成支付的操作。

公共業務和領域業務分離

如果通過靜態代理來寫,會使代理類急劇增加。而且多加了一個類,代碼量變大。由此引發了動態代理。

動態代理是爲了解決靜態代理每個類都需要寫代理的弊端。通過動態代理可以代理所有的類,分爲接口的代理,類的代理。

接口的代理就是jdk的動態代理,默認就是支持接口的動態代理。而類的代理需要通過ctilip,現在用javaseist比較多,ctilip反而較少。(ctilip,javaseist忘了怎麼寫的,隨便瞎寫一個名)

 

通過Proxy生成一個代理類,通過Proxy的靜態方法生成一個代理對象(代理實例),return後面這部分。通過代理實例去調用代理實例的方法時,如下圖中的getproxy是一個代理實例,通過代理實例調用代理對象(list.remove(0))時,會去觸發所對應的InvocationHandler實現的invoke方法。

也就是說生成的這個代理對象(list)一旦去調用方法(remove)(任何方法),就會去觸發對應的

InvocationHandler實現的invoke方法。觸發的時候,它就會將代理對象所調用的方法對象,傳給method

 

代理對象所調用方法的參數傳給agrs

對象本身傳給proxy

 

在invoke裏面我們可以加上公共的業務了

然後去調用方法本身去執行它,通過反射區執行它

spring的aop簡單來講就是動態代理的框架。動態代理需要我們去編寫,還比較麻煩。spring的aop只要通過spring來配置一下,把公共的業務放到一個類裏面,你把你的領域業務放出來,然後你通過spring的配置,然後它就會將你的公關業務放到領域業務中去,這種編程稱爲面向切面的編程aop,通過aop可以不去改變原有的代碼,增加新的功能。

關注點就是某種公共的業務,切面就是關注點的模塊化。

spring將公共的業務在哪個地方去執行分的很細,它分爲了在目標方法執行之前去執行,目標方法執行之後去執行,目標方法執行返回值之後去執行,目標方法執行發生異常的時候去執行,目標方法執行環繞之前之後去執行,所以分爲了前置通知,後置通知,環繞通知,異常通知等等。

通過連接點pointcut把公關業務和領域業務進行連接,以便在執行領域業務的時候去執行公共業務。連接點提供了一個非常好的表達式,可以通過execution這個表達式去指定某一個類的某一個方法,也可以指定某一個類下的所有方法,還可以指定某一個包下的所有類的所有方法。

並且spring提供了三種方式來實現aop。第一種,它提供了一個接口,我們只需要去實現它的接口就可以了,接口又提供了好幾個類型,有異常的類型。。。spring把這種類型稱爲通知/切面。

第二種,自定義,不具有任何的侵入性,我不用去實現spring給我們提供的接口,我也可以去實現這個業務。

直接配置,依然可以使我們的業務被執行。

第三種,通過spring提供的註解:@Aspect、@Before、@After、@Around

異常通知,當我們在實現spring給我們提供的接口的時候,異常通知接口比較特殊。異常通知其實是一個標識接口

Exception.java

package cn.sxt.log;

import java.lang.reflect.Method;

import org.springframework.aop.ThrowsAdvice;

public class ExceptionLog implements ThrowsAdvice{
	public void afterThrowing(Method method,Exception ex) 
			throws Throwable{
	}
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章