3.AOP

面向切面的Spring

在一般的程序開(kāi)發(fā)中,在每一個(gè)功能模塊中都有相同的操作,例如打印日志,事務(wù)操作等一系列重復(fù)動(dòng)作,而Spring AOP指的就是把這種重復(fù)工作橫向抽取出來(lái),讓程序員只需要關(guān)注業(yè)務(wù)

下面是關(guān)于AOP的相關(guān)術(shù)語(yǔ)

通知:簡(jiǎn)而言之就是被抽取出來(lái)的方法

連接點(diǎn):可以插入通知的點(diǎn)

切點(diǎn):需要被插入通知的點(diǎn)

切面:切點(diǎn)和通知構(gòu)成了一個(gè)切面

織入:把切面應(yīng)用到目標(biāo)對(duì)象并創(chuàng)建新的代理對(duì)象過(guò)程

使用注解的方式定義切面

可以在類前使用@Aspect,代表這個(gè)是個(gè)切面類,一下代表的是在perform方法調(diào)用之前執(zhí)行這個(gè)方法

@Aspect
public class Audience{

@Before("execution (** concert.Performace.perform(..))")
public void silenceCellPhones(){
    System.out.prinln("Silencing cell phones");
}

}

如果相同的切點(diǎn)被頻繁的使用,可以使用@pointcut,被定義為@Pointcut的實(shí)際方法內(nèi)容不重要,他只是作為一個(gè)標(biāo)識(shí)

public class Audience{
@Pointcut("execution (** concert.Performance.perform(..))")
public void performance(){}

@Before("performance()")
public void silenceCellPhones(){
    System.out.println("aa");
}

}

定義了切面類以后,需要使用配置來(lái)自動(dòng)裝配被@Aspect修飾的類

使用JavaConfig啟動(dòng)自動(dòng)代理

@Configuration
@EnableAspectJAutoProxy
@ComponentScan
public class ConcertConfig{
    @Bean
    public Audience audience(){
        return new Audience();
    }
}

使用xml

<context:component-scan base-package="concert" />
<aop:aspectj-autoproxy /> 啟動(dòng)AspectJ自動(dòng)代理

在xml中聲明切面

在前面所說(shuō)的切面定義中,使用java配置優(yōu)于xml配置,但是java配置的缺點(diǎn)就是必須要有源碼,所以,了解在xml中聲明切面是必須的


<aop:config>

<aop:aspect ref="Bean"> <!--引用一個(gè)切面類-->

<!--before 前置通知-->
<!--pointcut切入點(diǎn),代表需要被插入通知的方法的地方-->
<!--method 通知,代表插入的方法 -->
<aop:before 
    pointcut="execution(** 包名.類名.方法名(..))" 
    method="insertMethod" //通知
/>

同理 before改成after-returning代表后置通知,且方法被執(zhí)行完成以后才會(huì)執(zhí)行

after代表無(wú)論方法是否執(zhí)行成功都會(huì)執(zhí)行
after-thorwing代表拋出異常以后會(huì)執(zhí)行的方法
</aop:config>

如果多個(gè)通知都是在同一個(gè)切點(diǎn),這樣就要重復(fù)寫很多同樣的pointcut,我們可以為切點(diǎn)命名,如下,這樣我們就可以使用pointcut-ref直接指定id號(hào)獲取切點(diǎn),如果想要這個(gè)切點(diǎn)可以被所有切面所引用,可以把這個(gè)節(jié)點(diǎn)放在config下

<aop:config>
<aop:aspect ref="audience">
<aop:pointcut id="idName" expression="execution ..."
</aop:aspect>
</aop:config>

環(huán)繞通知

環(huán)繞通知指的是 既可以執(zhí)行前置通知 然后在執(zhí)行被通知方法,最后在執(zhí)行后置通知,環(huán)繞通知的好處是因?yàn)榄h(huán)繞通知是一個(gè)方法,所以變量是共享的,如果使用前置和后置通知,你在前置通知中定義的變量肯定是不能被后置通知訪問(wèn)的

環(huán)繞通知必須有參數(shù),因?yàn)樾枰{(diào)用被通知函數(shù)


public void roundMethod(ProceedingJoinPoint jp){
    try{
        //前置方法
        System.out.println("前置方法")
        jp.proceed();//調(diào)用被通知方法
        System.out.println("后置方法")
    }catch(Exception e){
        System.out.println("異常之后的方法");
    }

}

<aop:config>
    <aop:aspect ref="aspectBean">
        <aop:pointcut id="idName"
        expression ="execution(** 包名.類名.方法(..))"
        method ="roundMethod"
    </aop:aspect>
<aop:config>

通過(guò)以上就可以達(dá)到前置、后置、異常的通知 織入到切點(diǎn)中

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容