手机Av在线不卡,日韩精品校园婷婷五月天,国产轮理电影一区二区,日韩三级欧美视频

哈爾濱今日靈圖

[其他技能培訓(xùn)]
獵學(xué)網(wǎng)訂閱號(hào)
獵學(xué)網(wǎng)官方企業(yè)微信
位置: 獵學(xué)網(wǎng) > 學(xué)校機(jī)構(gòu) > 哈爾濱今日靈圖 > 學(xué)習(xí)資訊> 手把手教你用 Java 實(shí)現(xiàn) AOP

手把手教你用 Java 實(shí)現(xiàn) AOP

141 2017-04-19

介紹

眾所周知,AOP(面向切面編程)是Spring框架的特色功能之一。通過(guò)設(shè)置橫切關(guān)注點(diǎn)(crosscuttingconcerns),AOP提供了極高的擴(kuò)展性。那AOP在Spring中是怎樣運(yùn)作的呢?當(dāng)你只能使用corejava,卻需要AOP技術(shù)時(shí),這個(gè)問(wèn)題的解答變得極為關(guān)鍵。不僅如此,在高級(jí)技術(shù)崗位的面試中,此類問(wèn)題也常作為考題出現(xiàn)。這不,我的朋友最近參加了一個(gè)面試,就被問(wèn)到了這樣一個(gè)棘手的問(wèn)題——如何在不使用Spring及相關(guān)庫(kù),只用coreJava的條件下實(shí)現(xiàn)AOP。因此,我將在本文中提供一份大綱,幫助大家了解如何只用coreJava實(shí)現(xiàn)一個(gè)AOP(當(dāng)然啦,這種AOP在功能上有一定的局限性)。注意,本文不是一篇有關(guān)SpringAOP與JavaAOP的對(duì)比研究,而是有關(guān)在coreJava中借助固有的設(shè)計(jì)模式實(shí)現(xiàn)AOP的教程。

想必讀者已經(jīng)知道AOP是什么,也知道在Spring框架中如何使用它,因此本文只著眼于如何在不用Spring的前提下實(shí)現(xiàn)AOP。首先,我們得知道,Spring是借助了JDKproxy和CGlib兩種技術(shù)實(shí)現(xiàn)AOP的。JDKdynamicproxy提供了一種靈活的方式來(lái)hook一個(gè)方法并執(zhí)行指定的操作,但執(zhí)行操作時(shí)得有一個(gè)限制條件:必須先提供一個(gè)相關(guān)的接口以及該接口的實(shí)現(xiàn)類。實(shí)踐出真知,讓我們透過(guò)一個(gè)案例來(lái)理解這句吧!現(xiàn)在有一個(gè)計(jì)算器程序,用于完成一些數(shù)學(xué)運(yùn)算。讓我們來(lái)考慮下除法功能,此時(shí)的問(wèn)題是:如果coreframework已經(jīng)具備了一份實(shí)現(xiàn)除法的代碼,我們能否在代碼執(zhí)行時(shí)劫持(highjack)它并執(zhí)行額外的校驗(yàn)?zāi)??答案是肯定的,我將用下面提供的代碼片段來(lái)證明這點(diǎn)。首先來(lái)看基礎(chǔ)接口的代碼:

publicinterfaceCalculator{

publicintcalculate(inta,intb);

}

該接口實(shí)現(xiàn)類的代碼如下:

publicclassCalculatorImplimplementsCalculator{

@Override

publicintcalculate(inta,intb){

returna/b;

}

}

假設(shè)我們既不能修該上面的代碼,也不能對(duì)核心庫(kù)進(jìn)行任何改動(dòng),怎樣才能完美地實(shí)現(xiàn)校驗(yàn)功能呢?不如試下JDKdynamicproxy的功能吧。

publicclassSomeHandlerimplementsInvocationHandler{

//Codeomittedforsimplicity…..

@Override

publicObjectinvoke(Objectproxy,Methodmethod,Object[]params)throwsThrowable{

//Yourplexbusinessvalidationandlogic

Objectresult=method.invoke(targetObject,params);

returnresult;

}

}

讓我們通過(guò)測(cè)試類來(lái)看看由JDKdynamicproxy實(shí)現(xiàn)的校驗(yàn)功能的效果如何。

publicstaticvoidmain(String[]args){

CalculatorImplcalcImpl=newCalculatorImpl();

Calculatorproxied=(Calculator)ProxyFactory.getProxy(Calculator.class,calcImpl,

newSomeHandler(calcImpl));

intresult=proxied.calculate(20,10);

System.out.println("FInalResult:::"+result);

}

從結(jié)果可以看出,簡(jiǎn)單地實(shí)現(xiàn)功能強(qiáng)大的InvocationHandler接口,我們便能得到一個(gè)hookingimplementation。按照J(rèn)DK文檔的描述,InvocationHandler接口是借助一個(gè)代理實(shí)例(proxyinstance)來(lái)處理一個(gè)方法調(diào)用的。

現(xiàn)在我們已經(jīng)知道,InvocationHandler的invoke()方法能夠幫助我們解決問(wèn)題。那么再來(lái)解決一個(gè)新問(wèn)題——怎樣才能在方法執(zhí)行的前后執(zhí)行操作呢?說(shuō)的更具體一些,我們能通過(guò)添加多個(gè)aop(before、after、around)來(lái)hook一個(gè)方法嗎(譯注:原文為addmultipleaops,但我認(rèn)為Handler是充當(dāng)Aspect的角色)?答案同樣是肯定的。按照以下的步驟建立一個(gè)精簡(jiǎn)的代碼模板便能滿足這樣的需求:

1.

創(chuàng)建一個(gè)抽象類,用于將aop應(yīng)用于目標(biāo)對(duì)象上。

2.

創(chuàng)建名為BeforeHandler和AfterHandler的兩個(gè)aop。前者在方法執(zhí)行之前工作,而后者則在方法執(zhí)行結(jié)束后工作。

3.

創(chuàng)建一個(gè)代理類,使所有的aophandler和目標(biāo)對(duì)象只需作為參數(shù)傳入,就能創(chuàng)建一個(gè)hook。

4.

加入你自己的業(yè)務(wù)邏輯或者橫切關(guān)注點(diǎn)。

5.

最后,通過(guò)傳入相關(guān)的參數(shù)創(chuàng)建代理對(duì)象(proxyobject)。

技術(shù)實(shí)現(xiàn)概要

(譯注:此處是核心代碼片段,如果想運(yùn)行該實(shí)例,需進(jìn)入下方提供的鏈接下載完整代碼)

創(chuàng)建一個(gè)handler的抽象類:

publicabstractclassAbstractHandlerimplementsInvocationHandler{

privateObjecttargetObject;

publicvoidsetTargetObject(ObjecttargetObject){

this.targetObject=targetObject;

}

}

創(chuàng)建名為BeforeHandler和AfterHandler的兩個(gè)易擴(kuò)展的handler抽象類:

publicabstractclassBeforeHandlerextendsAbstractHandler{

publicabstractvoidhandleBefore(Objectproxy,Methodmethod,Object[]args);

publicObjectinvoke(Objectproxy,Methodmethod,Object[]args)throwsThrowable{

handleBefore(proxy,method,args);

returnmethod.invoke(getTargetObject(),args);

}

}

publicabstractclassAfterHandlerextendsAbstractHandler{

publicabstractvoidhandleAfter(Objectproxy,Methodmethod,Object[]args);

publicObjectinvoke(Objectproxy,Methodmethod,Object[]args)throwsThrowable{

Objectresult=method.invoke(getTargetObject(),args);

handleAfter(proxy,method,args);

returnresult;

}

}

創(chuàng)建Proxy的工廠類:

publicclassProxyFactory{

publicstaticObjectgetProxy(ObjecttargetObject,

Listhandlers){

//Codetogettheproxy

returnproxyObject;

}else{

returntargetObject;

}

}

}

以下為測(cè)試代碼:

CalculatorImplcalcImpl=newCalculatorImpl();

BeforeHandlerbefore=newBeforeHandlerImpl();

AfterHandlerafter=newAfterHandlerImpl();

Listhandlers=newArrayList();

handlers.add(before);

handlers.add(after);

Calculatorproxy=(Calculator)ProxyFactory.getProxy(calcImpl,

handlers);

intresult=proxy.calculate(20,10);

配置

以上的代碼片段簡(jiǎn)明扼要地解釋了AOP在結(jié)構(gòu)上的實(shí)現(xiàn)(structuralimplementation)。當(dāng)然,如果能通過(guò)實(shí)際的測(cè)試將其運(yùn)用到現(xiàn)實(shí)中去,那就再好不過(guò)了。讀者可在下面的鏈接中獲取完整的工程文件,并在Java編輯器中配置它們,最后通過(guò)其中的測(cè)試類來(lái)檢驗(yàn)效果。

總結(jié)

希望這篇簡(jiǎn)短的有關(guān)AOP文章能夠幫助到大家。需說(shuō)明的是,本文只實(shí)現(xiàn)了before和after兩種aop,而另外兩種,即“Around”和“Throw”,則希望讀者自行完成。

請(qǐng)聯(lián)系網(wǎng)站客服,了解詳細(xì)的優(yōu)惠課程信息~

優(yōu)質(zhì)、權(quán)威、便捷、省心

溫馨提示: 專業(yè)老師1對(duì)1為您解答    馬上填寫,¥1000 元豪禮免費(fèi)領(lǐng)!

掃一掃
獲取更多福利

×
獵學(xué)網(wǎng)
亚洲干屄久久久| 欧美熟妇6666| 欧美亚洲国产精品久久久九九九免费| 亚洲精品成AV人片| 亚洲欧美久久广西| 91麻豆激情| 日韩无码久久一区六区| 日韩伦理电影熟女网站| 日韩 视频 图片 二区| r日韩 欧美 国产精品| 午夜日本影院国产一二区| 性欧天天干天天性欧| 日韩久久香| 91精品久久久久久久久无码人妻| 国内自拍偷拍网| 本道一区二区久久无码激情| 亚洲AV专区专场| 日本不卡二区手机视频| 成人淫小说视频在线观看 | 97久久久久久久久久久久少妇超碰 | 站长搜索日韩欧美在线一级| 午夜试看看一区二区| 曰本人妇三级三少妇| 亚洲男人天堂精品一区| 精品无码一区二区三区爱欲九九 | 东南亚人妻偷拍交换激情视频区| 日韩免费AⅤ在线| 国产精品 偷拍自拍 下一篇| 国产午夜福利一区二区三区视频在线| 一区2区 3区精品| 欧美 在线 国产 一区| 日本一区区久久| 久久国产精品免费热| 国产精国产三级国产普通话-百度| 麻豆av观看好爽| 欧 美 婷婷五月| 人码一区二区三区| 免费播放的日B祝频一| 久久国产成人电影亚州无码| 亚洲国产麻豆久久| 黄色刺激成人AV|