Spring Aop

Advice通知

  • BeforeAdvice:接口MethodBeforeAdvice侨糟,方法before()
  • AfterAdvice:接口AfterReturningAdvice碍扔,方法afterReturning()
  • ThrowsAdvice:在拋出異常時回調(diào),這個回調(diào)是AOP通過反射機制完成的秕重。

Pointcut切點
概念:決定Advice通知應該作用于哪個連接點不同。返回一個MethodMatcher,由它來判斷是否需要對當前方法調(diào)用進行增強溶耘,或者是否需要對當前調(diào)用方法應用配置好的Advice通知二拐。

  • 通過正則表達式進行匹配
  • 通過方法名進行匹配
  • 等等

Spring AOP的設計和實現(xiàn)

JVM動態(tài)代理

這里寫圖片描述

Advisor通知器
概念:將Advicepointcut結合起來,可以定義應該使用哪個通知在哪個關注點使用凳兵。

建立AopProxy代理對象

ProxyFactoryBean:封裝了主要代理對象的生成過程百新,生成方式有兩種

  • JDK的Proxy
  • CGLIB


    這里寫圖片描述

JDK生成AopProxy代理對象

public Obejct getObject(ClassLoader classLoader) {
        if (logger.isDebugEnabled()) {
            logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());
        }
        Class[] proxiedInterfaces AopProxyUtils.completeProxiedInterfaces(this.advised);
        findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
        //這是調(diào)用JDK生成Proxy的地方
        return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
    }

攔截器調(diào)用的實現(xiàn)

JdkDynamicAopProxyinvoke攔截
當Proxy對象的代理方法被調(diào)用的時候,JdkDynamicAopProxyinvoke方法作為Proxy對象的回調(diào)函數(shù)被觸發(fā)庐扫,從而通過invoke的具體實現(xiàn)饭望,構造ReflectiveMethodInvocation對象來完成對目標對象方法調(diào)用的攔截或者說功能增強仗哨。

Cglib2AopProxyintercept攔截
JdkDynamicAopProxy的回調(diào)實現(xiàn)非常類似,唯一不同的是構造CglibMethodInvocation對象來完成攔截器鏈的調(diào)用铅辞。

對目標方法的調(diào)用

  • jdk:使用反射機制得到調(diào)用方法的反射對象厌漂,然后使用invoke啟動對方法反射對象的調(diào)用。
  • cglib:通過MethodProxy對象來直接invoke完成的

AOP攔截器鏈的調(diào)用
1. 先進行判斷斟珊,如果已經(jīng)運行到攔截器鏈的末尾苇倡,直接調(diào)用目標對象的實現(xiàn)方法
2. 否則,沿著攔截器鏈繼續(xù)進行囤踩,得到下一個攔截器旨椒,通過這個攔截器進行matches判斷,是否適用于橫切增強的場合高职,如果是钩乍,從攔截器中得到通知器,并啟動通知器的invoke方法進行切面增強
3. 結束之后怔锌,迭代調(diào)用proceed方法寥粹,直到攔截器鏈中的攔截器都完成以上的攔截過程為止

配置通知器
MethodBeforeAdviceAdapter的實現(xiàn)

 class MethodBeforeAdviceAdapter implements AdvisorAdapter, Serializable {

    @Override
    public boolean supportsAdvice(Advice advice) {
        return (advice instanceof MethodBeforeAdvice);
    }

    @Override
    public MethodInterceptor getInterceptor(Advisor advisor) {
        MethodBeforeAdvice advice = (MethodBeforeAdvice) advisor.getAdvice();
        return new MethodBeforeAdviceInterceptor(advice);
    }
}

MethodBeforeAdviceInterceptor的實現(xiàn)

public class MethodBeforeAdviceInterceptor implements MethodInterceptor, Serializable {

    private MethodBeforeAdvice advice;

    //為指定的Advice創(chuàng)建對應的MethodBeforeAdviceInterceptor對象
    public MethodBeforeAdviceInterceptor(MethodBeforeAdvice advice) {
        Assert.notNull(advice, "Advice must not be null");
        this.advice = advice;
    }

//這個invoke方法是攔截器的回調(diào)方法,會在代理對象的方法被調(diào)用時觸發(fā)回調(diào)
    @Override
    public Object invoke(MethodInvocation mi) throws Throwable {
        this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis() );
        return mi.proceed();
    }
}

AfterReturningAdviceInterceptor的實現(xiàn)

public class AfterReturningAdviceInterceptor implements MethodInterceptor, AfterAdvice, Serializable {

    private final AfterReturningAdvice advice;

    /**
     * Create a new AfterReturningAdviceInterceptor for the given advice.
     * @param advice the AfterReturningAdvice to wrap
     */
    public AfterReturningAdviceInterceptor(AfterReturningAdvice advice) {
        Assert.notNull(advice, "Advice must not be null");
        this.advice = advice;
    }

    @Override
    public Object invoke(MethodInvocation mi) throws Throwable {
        Object retVal = mi.proceed();
        this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
        return retVal;
    }

 }

Spring AOP的高級特性

HotSwappableTaregetSource:使用戶可以以線程安全的方式切換目標對象埃元,提供所謂的熱交換功能涝涤。

    public synchronized Object swap(Object newTarget) throws IllegalArgumentException {
        Assert.notNull(newTarget, "Target object must not be null");
        Object old = this.target;
        this.target = newTarget;
        return old;
    }

    public synchronized Object getTarget() {
        return this.target;
    }
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市岛杀,隨后出現(xiàn)的幾起案子阔拳,更是在濱河造成了極大的恐慌,老刑警劉巖类嗤,帶你破解...
    沈念sama閱讀 221,198評論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件糊肠,死亡現(xiàn)場離奇詭異,居然都是意外死亡遗锣,警方通過查閱死者的電腦和手機货裹,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評論 3 398
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來精偿,“玉大人弧圆,你說我怎么就攤上這事”恃剩” “怎么了搔预?”我有些...
    開封第一講書人閱讀 167,643評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長叶组。 經(jīng)常有香客問我拯田,道長,這世上最難降的妖魔是什么扶叉? 我笑而不...
    開封第一講書人閱讀 59,495評論 1 296
  • 正文 為了忘掉前任勿锅,我火速辦了婚禮帕膜,結果婚禮上,老公的妹妹穿的比我還像新娘溢十。我一直安慰自己垮刹,他們只是感情好,可當我...
    茶點故事閱讀 68,502評論 6 397
  • 文/花漫 我一把揭開白布张弛。 她就那樣靜靜地躺著荒典,像睡著了一般。 火紅的嫁衣襯著肌膚如雪吞鸭。 梳的紋絲不亂的頭發(fā)上寺董,一...
    開封第一講書人閱讀 52,156評論 1 308
  • 那天,我揣著相機與錄音刻剥,去河邊找鬼遮咖。 笑死,一個胖子當著我的面吹牛造虏,可吹牛的內(nèi)容都是我干的御吞。 我是一名探鬼主播,決...
    沈念sama閱讀 40,743評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼漓藕,長吁一口氣:“原來是場噩夢啊……” “哼陶珠!你這毒婦竟也來了?” 一聲冷哼從身側響起享钞,我...
    開封第一講書人閱讀 39,659評論 0 276
  • 序言:老撾萬榮一對情侶失蹤揍诽,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后栗竖,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體暑脆,經(jīng)...
    沈念sama閱讀 46,200評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,282評論 3 340
  • 正文 我和宋清朗相戀三年狐肢,在試婚紗的時候發(fā)現(xiàn)自己被綠了饵筑。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,424評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡处坪,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出架专,到底是詐尸還是另有隱情同窘,我是刑警寧澤,帶...
    沈念sama閱讀 36,107評論 5 349
  • 正文 年R本政府宣布部脚,位于F島的核電站想邦,受9級特大地震影響,放射性物質發(fā)生泄漏委刘。R本人自食惡果不足惜丧没,卻給世界環(huán)境...
    茶點故事閱讀 41,789評論 3 333
  • 文/蒙蒙 一鹰椒、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧呕童,春花似錦漆际、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至往声,卻和暖如春擂找,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背浩销。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評論 1 271
  • 我被黑心中介騙來泰國打工贯涎, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人慢洋。 一個月前我還...
    沈念sama閱讀 48,798評論 3 376
  • 正文 我出身青樓塘雳,卻偏偏與公主長得像,于是被迫代替她去往敵國和親且警。 傳聞我的和親對象是個殘疾皇子粉捻,可洞房花燭夜當晚...
    茶點故事閱讀 45,435評論 2 359