国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開(kāi)發(fā)設(shè)計(jì) > 正文

面向切面的spring

2019-11-06 06:08:47
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

       在軟件開(kāi)發(fā)中,分布于應(yīng)用多處的功能被稱(chēng)為橫切關(guān)注點(diǎn)。將這些橫切關(guān)注點(diǎn)和業(yè)務(wù)邏輯分離是面向切面鎖要解決的問(wèn)題。橫切關(guān)注點(diǎn)可以被模塊化為特殊的類(lèi),這些類(lèi)就叫做切面。這樣做的好處:每個(gè)關(guān)注點(diǎn)集中于一處,而不是分散到多出代碼中。服務(wù)模塊更簡(jiǎn)潔,它們只要關(guān)心核心功能就行了,其他轉(zhuǎn)移到切面中去了。

    

1.1定義AOP術(shù)語(yǔ)

     描述aop的常用術(shù)語(yǔ)有通知(advice)、切點(diǎn)(pointcut)、和連接點(diǎn)(join point)。 

通知:

      通知定義了切面是什么以及何時(shí)執(zhí)行,有5中通知類(lèi)型。

      1.Before:在方法執(zhí)行前調(diào)用通知。

      2.After:在方法執(zhí)行后調(diào)用通知,不管方法執(zhí)行是否成功。

      3.After-returning:在方法成功執(zhí)行后調(diào)用通知。

      4.After-throwing:在方法拋出異常時(shí)調(diào)用。

      5.Around:通知包含了被通知的方法,再被通知的方法調(diào)用之前和之后執(zhí)行相應(yīng)的自定義工作。

連接點(diǎn):連接點(diǎn)就是應(yīng)用執(zhí)行過(guò)程中能夠插入切面的一個(gè)點(diǎn)。這個(gè)點(diǎn)可以是調(diào)用方法時(shí)、調(diào)用方法后、拋出異常時(shí)等等,切面代碼可以利用這些點(diǎn)插入到應(yīng)用程序的正常流程中,并添加新的行為。

切點(diǎn):如果通知定義了什么和何時(shí),那么切點(diǎn)就定義了何處。切點(diǎn)有助于縮小連接點(diǎn)的范圍,因?yàn)橐粋€(gè)切面不需要通知所有的連接點(diǎn)。

切面(aspect):通知和切點(diǎn)的結(jié)合。它們定義了切面是什么,在何時(shí)何處執(zhí)行。

引入(Introduction):引入允許向現(xiàn)有的類(lèi)添加新方法或?qū)傩浴?/p>

織入(weaving):織入是將切面應(yīng)用到目標(biāo)對(duì)象來(lái)生成心得代理對(duì)象的過(guò)程。切面在指定的連接點(diǎn)中被織入目標(biāo)對(duì)象。目標(biāo)對(duì)象的生命周期中有多個(gè)點(diǎn)可以進(jìn)行織入。

1.編譯期:切面在目標(biāo)類(lèi)編譯時(shí)被織入。這種方式需要特殊的編譯器,AspectJ的織入編譯器就是這個(gè)時(shí)候織入的。

2.類(lèi)加載期:切面在類(lèi)加載到j(luò)vm是被織入。這種方式需要特殊的類(lèi)加載器,它可以再目標(biāo)類(lèi)被引入應(yīng)用之前加強(qiáng)目標(biāo)類(lèi)的字節(jié)碼。AspectJ的LTW就是這種方式織入的。

3.運(yùn)行期:切面在應(yīng)用運(yùn)行到某一時(shí)刻時(shí)被織入。一般情況下,在織入切面時(shí),AOP容器會(huì)為目標(biāo)對(duì)象創(chuàng)建一個(gè)代理對(duì)象。SPRing AOP就是這種方式織入的。

1.2 Spring對(duì)AOP的支持

      并不是所有的aop框架都是一樣的,它們?cè)谶B接點(diǎn)模型上有強(qiáng)弱之分。有三個(gè)AOP框架:AspectJ,JBoss AOP,Spring AOP。

spring提供4中具有特殊的aop支持:

1.基于代理的經(jīng)典AOP。

2.@AspectJ注解驅(qū)動(dòng)的切面。

3.純POJO切面。

4.注入式AspectJ切面(適合spring個(gè)版本)

      前三種方法都是基于代理的aop的變種,spring對(duì)aop的支持局限于方法的攔截。如果對(duì)aop的需求超過(guò)了對(duì)簡(jiǎn)單方法的攔截(比如對(duì)構(gòu)造方法或?qū)傩詳r截),那么需要在AspectJ里實(shí)現(xiàn)切面,利用依賴注入把Spring Bean注入到切面中。

2.使用切點(diǎn)選擇連接點(diǎn)

      spring支持的AspectJ切點(diǎn)指示器。

args()---------限制連接點(diǎn)匹配參數(shù)為指定類(lèi)型的執(zhí)行方法。

@args()---- 限制連接點(diǎn)匹配參數(shù)為指定注解標(biāo)注的執(zhí)行方法。

execution()  用于匹配時(shí)連接點(diǎn)的執(zhí)行方法

this()--------- 限制連接點(diǎn)匹配AOP代理的Bean的引用為指定類(lèi)型的類(lèi)

target()-------限制連接點(diǎn)匹配目標(biāo)對(duì)象為指定類(lèi)型的類(lèi)

@target()     限制連接點(diǎn)匹配特定的執(zhí)行對(duì)象,這些對(duì)象對(duì)應(yīng)的類(lèi)要有指定的注解

within()         限制連接點(diǎn)匹配指定的類(lèi)型

@within()      限制連接點(diǎn)匹配注解所標(biāo)注的類(lèi)型

@annotation 限制匹配帶有指定注解的連接點(diǎn)

      在Spring使用其他AspectJ指示器時(shí)會(huì)報(bào)illegalArgumentException。只有execution是唯一的執(zhí)行匹配,其他都是限制匹配。

2.1編寫(xiě)切點(diǎn)

execution(* com.xxx.A.get(..))上面第一個(gè)*表示返回類(lèi)型,*表示不關(guān)心返回類(lèi)型,隨便什么返回類(lèi)型都可以。然后是類(lèi)的全限定名和方法名。(..)表示使用任意參數(shù)都可以,就是說(shuō)所有的get()方法。
execution(xxx) && within(xxx) || execution(xxx) && arg(xxx) ||!execution(xxx) 2.2使用spring的bean指示器

      這個(gè)指示器允許在切點(diǎn)表達(dá)式中使用Bean的id來(lái)識(shí)別Bean。

execution(xxx) && bean(id)3 在xml中聲明切面

<aop:advisor>:定義AOP通知器

<aop:after>:定義AOP后置通知

<aop:after-returning>:定義AOP after-returning通知

<aop:after-throwing>:定義AOP after-throwing通知

<aop:around>:定義AOP環(huán)繞通知

<aop:aspect>:定義切面

<aop:aspectj-autoproxy>:?jiǎn)?dòng)@AspectJ注解驅(qū)動(dòng)的切面

<aop:before>:定義前置通知

<aop:config>:頂層的aop配置元素,大多數(shù)<aop:*>都在這里面

<aop:declear-parents>:為被通知的對(duì)象引入額外的接口,并透明的實(shí)現(xiàn)。

<aop:pointcut>:定義切點(diǎn)

<aop:config>   <aop:aspect id="bean的id">//定義切面        <aop:pointcut id="切點(diǎn)id" expression="execution()"/>//定義切點(diǎn)        <aop:before pointcut-ref="上面的切點(diǎn)id" method="bean里面的方法名"/>//定義前置通知    </aop:aspect></aop:config>如果pointcut想被多個(gè)切面引用,就把pointcut定義在config中。

3.1 聲明環(huán)繞通知

<aop:around  pointcut-ref="" method=""/>      環(huán)繞通知就是把前置通知和后置通知合起來(lái)變?yōu)橐粋€(gè)方法。如果前置通知和后置通知有聯(lián)系,那么可以用環(huán)繞通知來(lái)實(shí)現(xiàn),環(huán)繞通知的方法參數(shù)要有被通知的對(duì)象,這樣可以調(diào)用被通知的方法。

3.2為通知傳遞參數(shù)

 

<aop:before pointcut-ref="" method="" arg-names="name" />3.3 通過(guò)切面引入新功能

<aop:aspect>   <aop:declear-parents    types-matching=""//匹配類(lèi)   implement-interface=""//實(shí)現(xiàn)的接口   default-impl=""//接口的實(shí)現(xiàn)類(lèi)   delegate-ref=""//引入接口實(shí)現(xiàn)類(lèi)的Bean  id和上面的區(qū)別就是它是引用外部的一個(gè)Bean/></aop:aspect>4.注解切面

@AspectJ//定義切面class A{@Pointcut("execution()")//定義切點(diǎn)  public void a(){} @Before("a()") public void before(){System.out.println("before")}  @AfterReturning("a()")  public void afterReturning(){System.out.pringln("afterReturning")}}

        然后要在xml中加上<aop:aspectj-autoproxy/>,這個(gè)元素僅僅使用@AspectJ注解作為指引來(lái)創(chuàng)建基于代理的切面。本質(zhì)還是spring風(fēng)格的切面。

        <aop:aspect>和@AspectJ注解都是把一個(gè)POJO轉(zhuǎn)變?yōu)橐粋€(gè)切面的有效方式。<aop:aspect>可以引用任意一個(gè)Bean,而注解就要實(shí)現(xiàn)一個(gè)類(lèi)。

4.1注解環(huán)繞通知

@Around("a()")public void around(ProceedingJoinPoint a){    a.proceed();}

@DeclearParents(value=""defaultImpl="")private A a;


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 贺兰县| 聊城市| 四子王旗| 北宁市| 双峰县| 牡丹江市| 博客| 九龙坡区| 澄江县| 明溪县| 浦北县| 马尔康县| 白朗县| 富阳市| 垦利县| 晋江市| 青岛市| 马公市| 凤翔县| 鄂州市| 皮山县| 资溪县| 静安区| 定日县| 嵊州市| 工布江达县| 托里县| 星子县| 汕尾市| 新龙县| 东乡族自治县| 安康市| 尉氏县| 青冈县| 安溪县| 博野县| 建德市| 黄石市| 台州市| 大足县| 雅江县|