Spring AOP(1)

首先我們先來(lái)一個(gè)簡(jiǎn)單到不能簡(jiǎn)單的服務(wù)接口:

HelloService.java
package com.jd.www.jpl.service;
 
public interface HelloService {
        public void sayHello();
}

以及實(shí)現(xiàn)類

HelloServiceImpl.java
package com.jd.www.jpl.service.impl;
 
import com.jd.www.jpl.service.HelloService;
 
public class HelloServiceImpl implements HelloService {
 
    @Override
    public void sayHello() {
        System.out.println("hello world!!");
    }
}

接著創(chuàng)建一個(gè)攔截器接口

Interceptor.java
package com.jd.www.jpl.common.aop.proxy;
 
public interface Interceptor {
    // 前置通知
    void before();
 
    // 是否采用環(huán)繞通知
    boolean useAround();
 
    // 環(huán)繞通知
    Object around(Object target, Method method, Object[] args)
            throws IllegalAccessException, IllegalArgumentException, InvocationTargetException;
 
    // 事后方法
    void after();
 
    // 異常返回方法
    void afterThrowing();
 
    // 正常返回方法
    void afterReturning();
 
}

依據(jù)這個(gè)接口乳绕,可以給出一個(gè)很簡(jiǎn)單的實(shí)現(xiàn)

MyInterceptor.java
package com.jd.www.jpl.common.aop.proxy.impl;

import com.jd.www.jpl.common.aop.proxy.Interceptor;

public class MyInterceptor implements Interceptor {
    @Override
    public void before() {
        System.out.println("事前通知");
    }

    @Override
    public boolean useAround() {
        return true;
    }

    @Override
    public Object around(Object target, Method method, Object[] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
        System.out.println("環(huán)繞通知before");
        Object o = method.invoke(target,args);
        System.out.println("環(huán)繞通知after");
        return o;
    }

    @Override
    public void after() {
        System.out.println("事后通知");
    }

    @Override
    public void afterThrowing() {
        System.out.println("異常返回通知"); 
    }

    @Override
    public void afterReturning() {
        System.out.println("正常返回通知");
    }
}

如果用proxy去調(diào)用方法借杰,約定如下:

1播演、首先調(diào)用攔截器的before方法翔怎;

2缨伊、如果攔截器的useAround方法,返回為true辣卒,則執(zhí)行攔截器的around方法拧晕,不執(zhí)行target對(duì)象原有的sayHello方法紊扬;

3、無(wú)論結(jié)果如何都會(huì)執(zhí)行攔截器的after方法唉擂;

4餐屎、如果around方法有異常或者原有的target對(duì)象的sayHello方法有異常楔敌,則執(zhí)行攔截器的afterThrowing方法啤挎,否則執(zhí)行afterReturning方法。

好了卵凑,為了更好的說(shuō)明庆聘,我們來(lái)個(gè)流程圖。

流程圖

對(duì)應(yīng)的ProxyBean

package com.jd.www.jpl.common.aop.proxy.impl;

public class ProxyBean implements InvocationHandler {

    private Object target;
    private Interceptor interceptor;

    public static Object getProxyBean(Object target, Interceptor interceptor){
        ProxyBean proxyBean = new ProxyBean();
        proxyBean.target = target;
        proxyBean.interceptor = interceptor;
        return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(),proxyBean);
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        boolean e = false;
        Object ret = null;
        MyInterceptor myInterceptor = new MyInterceptor();
        myInterceptor.before();
        try {
            if(interceptor.useAround()){
                ret = myInterceptor.around(target,method,args);
            }else {
                ret = method.invoke(target,args);
            }
        } catch (InvocationTargetException | IllegalAccessException | IllegalArgumentException ex) {
            e = true;
        }
        myInterceptor.after();
        if(e){
            myInterceptor.afterThrowing();
        }else{
            myInterceptor.afterReturning();
            return ret;
        }
        return null;
    }
}

創(chuàng)建測(cè)試用例

SpringAopTest.java
package com.jd.jmq.consumer;

import com.jd.www.jpl.common.aop.proxy.impl.MyInterceptor;
import com.jd.www.jpl.common.aop.proxy.impl.ProxyBean;
import com.jd.www.jpl.service.HelloService;
import com.jd.www.jpl.service.impl.HelloServiceImpl;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath*:spring/spring-consumer.xml"})
public class SpringAopTest {
    @Test
    public void testAop(){
        HelloService helloService = new HelloServiceImpl();
        HelloService proxy = (HelloService) ProxyBean.getProxyBean(helloService,new MyInterceptor());
        proxy.sayHello();
    }
}

運(yùn)行結(jié)果:


結(jié)果
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末勺卢,一起剝皮案震驚了整個(gè)濱河市伙判,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌黑忱,老刑警劉巖宴抚,帶你破解...
    沈念sama閱讀 216,324評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異甫煞,居然都是意外死亡菇曲,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,356評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門抚吠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)常潮,“玉大人,你說(shuō)我怎么就攤上這事楷力『笆剑” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 162,328評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵萧朝,是天一觀的道長(zhǎng)岔留。 經(jīng)常有香客問(wèn)我,道長(zhǎng)检柬,這世上最難降的妖魔是什么献联? 我笑而不...
    開(kāi)封第一講書人閱讀 58,147評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮何址,結(jié)果婚禮上里逆,老公的妹妹穿的比我還像新娘。我一直安慰自己头朱,他們只是感情好运悲,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,160評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著项钮,像睡著了一般班眯。 火紅的嫁衣襯著肌膚如雪希停。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 51,115評(píng)論 1 296
  • 那天署隘,我揣著相機(jī)與錄音宠能,去河邊找鬼。 笑死磁餐,一個(gè)胖子當(dāng)著我的面吹牛违崇,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播诊霹,決...
    沈念sama閱讀 40,025評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼羞延,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了脾还?” 一聲冷哼從身側(cè)響起伴箩,我...
    開(kāi)封第一講書人閱讀 38,867評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎鄙漏,沒(méi)想到半個(gè)月后嗤谚,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,307評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡怔蚌,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,528評(píng)論 2 332
  • 正文 我和宋清朗相戀三年巩步,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片桦踊。...
    茶點(diǎn)故事閱讀 39,688評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡椅野,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出钞钙,到底是詐尸還是另有隱情鳄橘,我是刑警寧澤声离,帶...
    沈念sama閱讀 35,409評(píng)論 5 343
  • 正文 年R本政府宣布芒炼,位于F島的核電站,受9級(jí)特大地震影響术徊,放射性物質(zhì)發(fā)生泄漏本刽。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,001評(píng)論 3 325
  • 文/蒙蒙 一赠涮、第九天 我趴在偏房一處隱蔽的房頂上張望子寓。 院中可真熱鬧,春花似錦笋除、人聲如沸斜友。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,657評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)鲜屏。三九已至烹看,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間洛史,已是汗流浹背惯殊。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,811評(píng)論 1 268
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留也殖,地道東北人土思。 一個(gè)月前我還...
    沈念sama閱讀 47,685評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像忆嗜,于是被迫代替她去往敵國(guó)和親己儒。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,573評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容

  • 上一篇文章spring源碼系列-從@Autowired與@Resource異同中看依賴注入中捆毫,我們著重分析了依賴注...
    默寫流年閱讀 315評(píng)論 0 2
  • 一址愿,aop 術(shù)語(yǔ) 1.切面Aspect: Aspect 聲明類似于 Java 中的類聲明,在 Aspect 中會(huì)包...
    張開(kāi)翔閱讀 159評(píng)論 0 0
  • 一冻璃、 AOP 簡(jiǎn)介 1.1 什么是 AOP AOP (Aspect Orient Programming),直譯過(guò)...
    GaaraZ閱讀 248評(píng)論 0 0
  • Spring AOP解決問(wèn)題 相比較于面向過(guò)程程序設(shè)計(jì)(POP)响谓,面向?qū)ο蟪绦蛟O(shè)計(jì)(OOP)更加注重封裝與隔離,以...
    桴海閱讀 192評(píng)論 0 0
  • AOP術(shù)語(yǔ) 連接點(diǎn)(Jointpoint):表示需要在程序中插入橫切關(guān)注點(diǎn)的擴(kuò)展點(diǎn)省艳,連接點(diǎn)可能是類初始化娘纷、方法執(zhí)行...
    黃二的NPE閱讀 940評(píng)論 0 0