久久福利_99r_国产日韩在线视频_直接看av的网站_中文欧美日韩_久久一

您的位置:首頁技術(shù)文章
文章詳情頁

解析Spring中面向切面編程

瀏覽:167日期:2023-07-11 08:05:26
目錄一、AOP——另一種編程思想1.1、什么是 AOP1.2、為什么需要 AOP1.3、AOP 實(shí)現(xiàn)分類二、AOP 術(shù)語三、初步認(rèn)識(shí) Spring AOP3.1、Spring AOP 的特點(diǎn)3.2、Spring AOP 的簡單例子四、通過注解配置 Spring AOP4.1、通過注解聲明切點(diǎn)指示器4.2、通過注解聲明 5 種通知類型4.3、通過注解聲明切點(diǎn)表達(dá)式4.4、通過注解處理通知中的參數(shù)4.5、通過注解配置織入的方式五、通過 XML 配置文件聲明切面5.1、XML 配置文件中切點(diǎn)指示器5.2、XML 文件配置 AOP 實(shí)例5.3、XML 文件配置聲明切點(diǎn)5.4、XML文件配置為通知傳遞參數(shù)5.5、Xml 文件配置織入的方式六、總結(jié)一、AOP——另一種編程思想1.1、什么是 AOP

AOP (Aspect Orient Programming),直譯過來就是 面向切面編程。AOP 是一種編程思想,是面向?qū)ο缶幊蹋∣OP)的一種補(bǔ)充。面向?qū)ο缶幊虒⒊绦虺橄蟪筛鱾€(gè)層次的對象,而面向切面編程是將程序抽象成各個(gè)切面。

從《Spring實(shí)戰(zhàn)(第4版)》圖書中扒了一張圖:

解析Spring中面向切面編程

從該圖可以很形象地看出,所謂切面,相當(dāng)于應(yīng)用對象間的橫切點(diǎn),我們可以將其單獨(dú)抽象為單獨(dú)的模塊。

1.2、為什么需要 AOP

想象下面的場景,開發(fā)中在多個(gè)模塊間有某段重復(fù)的代碼,我們通常是怎么處理的?顯然,沒有人會(huì)靠“復(fù)制粘貼”吧。在傳統(tǒng)的面向過程編程中,我們也會(huì)將這段代碼,抽象成一個(gè)方法,然后在需要的地方分別調(diào)用這個(gè)方法,這樣當(dāng)這段代碼需要修改時(shí),我們只需要改變這個(gè)方法就可以了。然而需求總是變化的,有一天,新增了一個(gè)需求,需要再多出做修改,我們需要再抽象出一個(gè)方法,然后再在需要的地方分別調(diào)用這個(gè)方法,又或者我們不需要這個(gè)方法了,我們還是得刪除掉每一處調(diào)用該方法的地方。實(shí)際上涉及到多個(gè)地方具有相同的修改的問題我們都可以通過 AOP 來解決。

1.3、AOP 實(shí)現(xiàn)分類

AOP 要達(dá)到的效果是,保證開發(fā)者不修改源代碼的前提下,去為系統(tǒng)中的業(yè)務(wù)組件添加某種通用功能。AOP 的本質(zhì)是由 AOP 框架修改業(yè)務(wù)組件的多個(gè)方法的源代碼,看到這其實(shí)應(yīng)該明白了,AOP 其實(shí)就是前面一篇文章講的代理模式的典型應(yīng)用。按照 AOP 框架修改源代碼的時(shí)機(jī),可以將其分為兩類:

靜態(tài) AOP 實(shí)現(xiàn), AOP 框架在編譯階段對程序源代碼進(jìn)行修改,生成了靜態(tài)的 AOP 代理類(生成的 *.class 文件已經(jīng)被改掉了,需要使用特定的編譯器),比如 AspectJ。 動(dòng)態(tài) AOP 實(shí)現(xiàn), AOP 框架在運(yùn)行階段對動(dòng)態(tài)生成代理對象(在內(nèi)存中以 JDK 動(dòng)態(tài)代理,或 CGlib 動(dòng)態(tài)地生成 AOP 代理類),如 SpringAOP。

下面給出常用 AOP 實(shí)現(xiàn)比較

解析Spring中面向切面編程

如不清楚動(dòng)態(tài)代理的,可參考我前面的一篇文章,有講解靜態(tài)代理、JDK動(dòng)態(tài)代理和 CGlib 動(dòng)態(tài)代理。

二、AOP 術(shù)語

AOP 領(lǐng)域中的特性術(shù)語:

通知(Advice): AOP 框架中的增強(qiáng)處理。通知描述了切面何時(shí)執(zhí)行以及如何執(zhí)行增強(qiáng)處理。 連接點(diǎn)(join point): 連接點(diǎn)表示應(yīng)用執(zhí)行過程中能夠插入切面的一個(gè)點(diǎn),這個(gè)點(diǎn)可以是方法的調(diào)用、異常的拋出。在 Spring AOP 中,連接點(diǎn)總是方法的調(diào)用。 切點(diǎn)(PointCut): 可以插入增強(qiáng)處理的連接點(diǎn)。 切面(Aspect): 切面是通知和切點(diǎn)的結(jié)合。 引入(Introduction):引入允許我們向現(xiàn)有的類添加新的方法或者屬性。 織入(Weaving): 將增強(qiáng)處理添加到目標(biāo)對象中,并創(chuàng)建一個(gè)被增強(qiáng)的對象,這個(gè)過程就是織入。

概念看起來總是有點(diǎn)懵,并且上述術(shù)語,不同的參考書籍上翻譯還不一樣,所以需要慢慢在應(yīng)用中理解。

三、初步認(rèn)識(shí) Spring AOP3.1、Spring AOP 的特點(diǎn)

AOP 框架有很多種,1.3節(jié)中介紹了 AOP 框架的實(shí)現(xiàn)方式有可能不同, Spring 中的 AOP 是通過動(dòng)態(tài)代理實(shí)現(xiàn)的。不同的 AOP 框架支持的連接點(diǎn)也有所區(qū)別,例如,AspectJ 和 JBoss,除了支持方法切點(diǎn),它們還支持字段和構(gòu)造器的連接點(diǎn)。而 Spring AOP 不能攔截對對象字段的修改,也不支持構(gòu)造器連接點(diǎn),我們無法在 Bean 創(chuàng)建時(shí)應(yīng)用通知。

3.2、Spring AOP 的簡單例子

下面先上代碼,對著代碼說比較好說,看下面這個(gè)例子:這個(gè)例子是基于gradle創(chuàng)建的,首先 build.gradle 文件添加依賴:

dependencies { compile ’org.springframework:spring-context:5.0.6.RELEASE’}

首先創(chuàng)建一個(gè)接口 IBuy.java

package com.sharpcj.aopdemo.test1;public interface IBuy { String buy();}

Boy 和 Gril 兩個(gè)類分別實(shí)現(xiàn)了這個(gè)接口:

Boy.java

package com.sharpcj.aopdemo.test1;import org.springframework.stereotype.Component;@Componentpublic class Boy implements IBuy { @Override public String buy() {System.out.println('男孩買了一個(gè)游戲機(jī)');return '游戲機(jī)'; }}

Girl.java

package com.sharpcj.aopdemo.test1;import org.springframework.stereotype.Component;@Componentpublic class Girl implements IBuy { @Override public String buy() {System.out.println('女孩買了一件漂亮的衣服');return '衣服'; }}

配置文件, AppConfig.java

package com.sharpcj.aopdemo;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;@Configuration@ComponentScan(basePackageClasses = {com.sharpcj.aopdemo.test1.IBuy.class})public class AppConfig {}

測試類, AppTest.java

package com.sharpcj.aopdemo;import com.sharpcj.aopdemo.test1.Boy;import com.sharpcj.aopdemo.test1.Girl;import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class AppTest { public static void main(String[] args) {AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);Boy boy = context.getBean('boy',Boy.class);Girl girl = (Girl) context.getBean('girl');boy.buy();girl.buy(); }}

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

解析Spring中面向切面編程

這里運(yùn)用SpringIOC里的自動(dòng)部署。現(xiàn)在需求改變了,我們需要在男孩和女孩的 buy 方法之前,需要打印出“男孩女孩都買了自己喜歡的東西”。用 Spring AOP 來實(shí)現(xiàn)這個(gè)需求只需下面幾個(gè)步驟:

1、 既然用到 Spring AOP, 首先在 build.gralde 文件中引入相關(guān)依賴:

dependencies { compile ’org.springframework:spring-context:5.0.6.RELEASE’ compile ’org.springframework:spring-aspects:5.0.6.RELEASE’}

2、 定義一個(gè)切面類,BuyAspectJ.java

package com.sharpcj.aopdemo.test1;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before;import org.springframework.stereotype.Component;@Aspect@Componentpublic class BuyAspectJ { @Before('execution(* com.sharpcj.aopdemo.test1.IBuy.buy(..))') public void haha(){System.out.println('男孩女孩都買自己喜歡的東西'); }}

這個(gè)類,我們使用了注解 @Component 表明它將作為一個(gè)Spring Bean 被裝配,使用注解 @Aspect 表示它是一個(gè)切面。

類中只有一個(gè)方法 haha 我們使用 @Before 這個(gè)注解,表示他將在方法執(zhí)行之前執(zhí)行。關(guān)于這個(gè)注解后文再作解釋。

參數(shù)('execution(* com.sharpcj.aopdemo.test1.IBuy.buy(..))') 聲明了切點(diǎn),表明在該切面的切點(diǎn)是com.sharpcj.aopdemo.test1.Ibuy這個(gè)接口中的buy方法。至于為什么這么寫,下文再解釋。

3、 在配置文件中啟用AOP切面功能

package com.sharpcj.aopdemo;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.EnableAspectJAutoProxy;@Configuration@ComponentScan(basePackageClasses = {com.sharpcj.aopdemo.test1.IBuy.class})@EnableAspectJAutoProxy(proxyTargetClass = true)public class AppConfig {}

我們在配置文件類增加了@EnableAspectJAutoProxy注解,啟用了 AOP 功能,參數(shù)proxyTargetClass的值設(shè)為了 true 。默認(rèn)值是 false,兩者的區(qū)別下文再解釋。

OK,下面只需測試代碼,運(yùn)行結(jié)果如下:

解析Spring中面向切面編程

我們看到,結(jié)果與我們需求一致,我們并沒有修改 Boy 和 Girl 類的 Buy 方法,也沒有修改測試類的代碼,幾乎是完全無侵入式地實(shí)現(xiàn)了需求。這就是 AOP 的“神奇”之處。

四、通過注解配置 Spring AOP4.1、通過注解聲明切點(diǎn)指示器

Spring AOP 所支持的 AspectJ 切點(diǎn)指示器

解析Spring中面向切面編程

在spring中嘗試使用AspectJ其他指示器時(shí),將會(huì)拋出IllegalArgumentException異常。

當(dāng)我們查看上面展示的這些spring支持的指示器時(shí),注意只有execution指示器是唯一的執(zhí)行匹配,而其他的指示器都是用于限制匹配的。這說明execution指示器是我們在編寫切點(diǎn)定義時(shí)最主要使用的指示器,在此基礎(chǔ)上,我們使用其他指示器來限制所匹配的切點(diǎn)。

下圖的切點(diǎn)表達(dá)式表示當(dāng)Instrument的play方法執(zhí)行時(shí)會(huì)觸發(fā)通知。

解析Spring中面向切面編程

我們使用execution指示器選擇Instrument的play方法,方法表達(dá)式以 * 號(hào)開始,標(biāo)識(shí)我們不關(guān)心方法的返回值類型。然后我們指定了全限定類名和方法名。對于方法參數(shù)列表,我們使用 .. 標(biāo)識(shí)切點(diǎn)選擇任意的play方法,無論該方法的入?yún)⑹鞘裁础?/p>

多個(gè)匹配之間我們可以使用鏈接符 &&、||、!來表示 “且”、“或”、“非”的關(guān)系。但是在使用 XML 文件配置時(shí),這些符號(hào)有特殊的含義,所以我們使用 “and”、“or”、“not”來表示。

舉例:

限定該切點(diǎn)僅匹配的包是 com.sharpcj.aopdemo.test1,可以使用

execution(* com.sharpcj.aopdemo.test1.IBuy.buy(..)) && within(com.sharpcj.aopdemo.test1.*)

在切點(diǎn)中選擇 bean,可以使用

execution(* com.sharpcj.aopdemo.test1.IBuy.buy(..)) && bean(girl)

修改 BuyAspectJ.java

package com.sharpcj.aopdemo.test1;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before;import org.springframework.stereotype.Component;@Aspect@Componentpublic class BuyAspectJ { @Before('execution(* com.sharpcj.aopdemo.test1.IBuy.buy(..)) && within(com.sharpcj.aopdemo.test1.*) && bean(girl)') public void hehe(){System.out.println('男孩女孩都買自己喜歡的東西'); }}

此時(shí),切面只會(huì)對 Girl.java 這個(gè)類生效,執(zhí)行結(jié)果:

解析Spring中面向切面編程

細(xì)心的你,可能發(fā)現(xiàn)了,切面中的方法名,已經(jīng)被我悄悄地從haha改成了hehe,絲毫沒有影響結(jié)果,說明方法名沒有影響。和 Spring IOC 中用 java 配置文件裝配 Bean 時(shí),用@Bean 注解修飾的方法名一樣,沒有影響。

4.2、通過注解聲明 5 種通知類型

Spring AOP 中有 5 中通知類型,分別如下:

解析Spring中面向切面編程

下面修改切面類:

package com.sharpcj.aopdemo.test1;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.*;import org.springframework.stereotype.Component;@Aspect@Componentpublic class BuyAspectJ { @Before('execution(* com.sharpcj.aopdemo.test1.IBuy.buy(..))') public void hehe() {System.out.println('before ...'); } @After('execution(* com.sharpcj.aopdemo.test1.IBuy.buy(..))') public void haha() {System.out.println('After ...'); } @AfterReturning('execution(* com.sharpcj.aopdemo.test1.IBuy.buy(..))') public void xixi() {System.out.println('AfterReturning ...'); } @Around('execution(* com.sharpcj.aopdemo.test1.IBuy.buy(..))') public void xxx(ProceedingJoinPoint pj) {try { System.out.println('Around aaa ...'); pj.proceed(); System.out.println('Around bbb ...');} catch (Throwable throwable) { throwable.printStackTrace();} }}

為了方便看效果,我們測試類中,只要 Boy 類:

package com.sharpcj.aopdemo;import com.sharpcj.aopdemo.test1.Boy;import com.sharpcj.aopdemo.test1.Girl;import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class AppTest { public static void main(String[] args) {AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);Boy boy = context.getBean('boy',Boy.class);Girl girl = (Girl) context.getBean('girl');boy.buy();// girl.buy(); }}

執(zhí)行結(jié)果如下:

解析Spring中面向切面編程

結(jié)果顯而易見。指的注意的是 @Around 修飾的環(huán)繞通知類型,是將整個(gè)目標(biāo)方法封裝起來了,在使用時(shí),我們傳入了 ProceedingJoinPoint 類型的參數(shù),這個(gè)對象是必須要有的,并且需要調(diào)用 ProceedingJoinPoint 的 proceed() 方法。 如果沒有調(diào)用 該方法,執(zhí)行結(jié)果為 :

Around aaa ...

Around bbb ...

After ...

AfterReturning ...

可見,如果不調(diào)用該對象的 proceed() 方法,表示原目標(biāo)方法被阻塞調(diào)用,當(dāng)然也有可能你的實(shí)際需求就是這樣。

4.3、通過注解聲明切點(diǎn)表達(dá)式

如你看到的,上面我們寫的多個(gè)通知使用了相同的切點(diǎn)表達(dá)式,對于像這樣頻繁出現(xiàn)的相同的表達(dá)式,我們可以使用 @Pointcut注解聲明切點(diǎn)表達(dá)式,然后使用表達(dá)式,修改代碼如下:

BuyAspectJ.java

package com.sharpcj.aopdemo.test1;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.*;import org.springframework.stereotype.Component;@Aspect@Componentpublic class BuyAspectJ { @Pointcut('execution(* com.sharpcj.aopdemo.test1.IBuy.buy(..))') public void point(){} @Before('point()') public void hehe() {System.out.println('before ...'); } @After('point()') public void haha() {System.out.println('After ...'); } @AfterReturning('point()') public void xixi() {System.out.println('AfterReturning ...'); } @Around('point()') public void xxx(ProceedingJoinPoint pj) {try { System.out.println('Around aaa ...'); pj.proceed(); System.out.println('Around bbb ...');} catch (Throwable throwable) { throwable.printStackTrace();} }}

程序運(yùn)行結(jié)果沒有變化。

這里,我們使用

@Pointcut('execution(* com.sharpcj.aopdemo.test1.IBuy.buy(..))')public void point(){}

聲明了一個(gè)切點(diǎn)表達(dá)式,該方法 point 的內(nèi)容并不重要,方法名也不重要,實(shí)際上它只是作為一個(gè)標(biāo)識(shí),供通知使用。

4.4、通過注解處理通知中的參數(shù)

上面的例子,我們要進(jìn)行增強(qiáng)處理的目標(biāo)方法沒有參數(shù),下面我們來說說有參數(shù)的情況,并且在增強(qiáng)處理中使用該參數(shù)。下面我們給接口增加一個(gè)參數(shù),表示購買所花的金錢。通過AOP 增強(qiáng)處理,如果女孩買衣服超過了 68 元,就可以贈(zèng)送一雙襪子。

更改代碼如下:

IBuy.java

package com.sharpcj.aopdemo.test1;public interface IBuy { String buy(double price);}

Girl.java

package com.sharpcj.aopdemo.test1;import org.springframework.stereotype.Component;@Componentpublic class Girl implements IBuy { @Override public String buy(double price) {System.out.println(String.format('女孩花了%s元買了一件漂亮的衣服', price));return '衣服'; }}

Boy.java

package com.sharpcj.aopdemo.test1;import org.springframework.stereotype.Component;@Componentpublic class Boy implements IBuy { @Override public String buy(double price) {System.out.println(String.format('男孩花了%s元買了一個(gè)游戲機(jī)', price));return '游戲機(jī)'; }}

再看 BuyAspectJ 類,我們將之前的通知都注釋掉。用一個(gè)環(huán)繞通知來實(shí)現(xiàn)這個(gè)功能:

package com.sharpcj.aopdemo.test1;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.*;import org.springframework.stereotype.Component;@Aspect@Componentpublic class BuyAspectJ { /* @Pointcut('execution(* com.sharpcj.aopdemo.test1.IBuy.buy(..))') public void point(){} @Before('point()') public void hehe() {System.out.println('before ...'); } @After('point()') public void haha() {System.out.println('After ...'); } @AfterReturning('point()') public void xixi() {System.out.println('AfterReturning ...'); } @Around('point()') public void xxx(ProceedingJoinPoint pj) {try { System.out.println('Around aaa ...'); pj.proceed(); System.out.println('Around bbb ...');} catch (Throwable throwable) { throwable.printStackTrace();} } */ @Pointcut('execution(String com.sharpcj.aopdemo.test1.IBuy.buy(double)) && args(price) && bean(girl)') public void gif(double price) { } @Around('gif(price)') public String hehe(ProceedingJoinPoint pj, double price){try { pj.proceed(); if (price > 68) {System.out.println('女孩買衣服超過了68元,贈(zèng)送一雙襪子');return '衣服和襪子'; }} catch (Throwable throwable) { throwable.printStackTrace();}return '衣服'; }}

前文提到,當(dāng)不關(guān)心方法返回值的時(shí)候,我們在編寫切點(diǎn)指示器的時(shí)候使用了 * , 當(dāng)不關(guān)心方法參數(shù)的時(shí)候,我們使用了 ..。現(xiàn)在如果我們需要傳入?yún)?shù),并且有返回值的時(shí)候,則需要使用對應(yīng)的類型。在編寫通知的時(shí)候,我們也需要聲明對應(yīng)的返回值類型和參數(shù)類型。

測試類:AppTest.java

package com.sharpcj.aopdemo;import com.sharpcj.aopdemo.test1.Boy;import com.sharpcj.aopdemo.test1.Girl;import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class AppTest { public static void main(String[] args) {AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);Boy boy = context.getBean('boy',Boy.class);Girl girl = (Girl) context.getBean('girl');String boyBought = boy.buy(35);String girlBought = girl.buy(99.8);System.out.println('男孩買到了:' + boyBought);System.out.println('女孩買到了:' + girlBought); }}

測試結(jié)果:

解析Spring中面向切面編程可以看到,我們成功通過 AOP 實(shí)現(xiàn)了需求,并將結(jié)果打印了出來。

4.5、通過注解配置織入的方式

前面還有一個(gè)遺留問題,在配置文件中,我們用注解 @EnableAspectJAutoProxy() 啟用Spring AOP 的時(shí)候,我們給參數(shù) proxyTargetClass 賦值為 true,如果我們不寫參數(shù),默認(rèn)為 false。這個(gè)時(shí)候運(yùn)行程序,程序拋出異常

解析Spring中面向切面編程

這是一個(gè)強(qiáng)制類型轉(zhuǎn)換異常。為什么會(huì)拋出這個(gè)異常呢?或許已經(jīng)能夠想到,這跟Spring AOP 動(dòng)態(tài)代理的機(jī)制有關(guān),這個(gè) proxyTargetClass 參數(shù)決定了代理的機(jī)制。當(dāng)這個(gè)參數(shù)為 false 時(shí),通過jdk的基于接口的方式進(jìn)行織入,這時(shí)候代理生成的是一個(gè)接口對象,將這個(gè)接口對象強(qiáng)制轉(zhuǎn)換為實(shí)現(xiàn)該接口的一個(gè)類,自然就拋出了上述類型轉(zhuǎn)換異常。

反之,proxyTargetClass 為 true,則會(huì)使用 cglib 的動(dòng)態(tài)代理方式。這種方式的缺點(diǎn)是拓展類的方法被final修飾時(shí),無法進(jìn)行織入。

測試一下,我們將 proxyTargetClass 參數(shù)設(shè)為 true,同時(shí)將 Girl.java 的 Buy 方法用 final 修飾:

AppConfig.java

package com.sharpcj.aopdemo;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.EnableAspectJAutoProxy;@Configuration@ComponentScan(basePackageClasses = {com.sharpcj.aopdemo.test1.IBuy.class})@EnableAspectJAutoProxy(proxyTargetClass = true)public class AppConfig {}

Girl.java

package com.sharpcj.aopdemo.test1;import org.springframework.stereotype.Component;@Componentpublic class Girl implements IBuy { @Override public final String buy(double price) {System.out.println(String.format('女孩花了%s元買了一件漂亮的衣服', price));return '衣服'; }}

此時(shí)運(yùn)行結(jié)果:

解析Spring中面向切面編程

可以看到,我們的切面并沒有織入生效。

五、通過 XML 配置文件聲明切面

前面的示例中,我們已經(jīng)展示了如何通過注解配置去聲明切面,下面我們看看如何在 XML 文件中聲明切面。下面先列出 XML 中聲明 AOP 的常用元素:

解析Spring中面向切面編程

我們依然可以使用 <aop:aspectj-autoproxy> 元素,他能夠自動(dòng)代理AspectJ注解的通知類。

5.1、XML 配置文件中切點(diǎn)指示器

在XML配置文件中,切點(diǎn)指示器表達(dá)式與通過注解配置的寫法基本一致,區(qū)別前面有提到,即XML文件中需要使用 “and”、“or”、“not”來表示 “且”、“或”、“非”的關(guān)系。

5.2、XML 文件配置 AOP 實(shí)例

下面我們不使用任何注解改造上面的例子:BuyAspectJ.java

package com.sharpcj.aopdemo.test2;import org.aspectj.lang.ProceedingJoinPoint;public class BuyAspectJ { public void hehe() {System.out.println('before ...'); } public void haha() {System.out.println('After ...'); } public void xixi() {System.out.println('AfterReturning ...'); } public void xxx(ProceedingJoinPoint pj) {try { System.out.println('Around aaa ...'); pj.proceed(); System.out.println('Around bbb ...');} catch (Throwable throwable) { throwable.printStackTrace();} }}

在 Resource 目錄下新建一個(gè)配置文件 aopdemo.xml :

<?xml version='1.0' encoding='UTF-8'?><beans xmlns='http://www.springframework.org/schema/beans' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:aop='http://www.springframework.org/schema/aop' xsi:schemaLocation='http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd'> <bean class='com.sharpcj.aopdemo.test2.Boy'></bean> <bean class='com.sharpcj.aopdemo.test2.Girl'></bean> <bean class='com.sharpcj.aopdemo.test2.BuyAspectJ'></bean> <aop:config proxy-target-class='true'><aop:aspect ref='buyAspectJ'> <aop:before pointcut='execution(* com.sharpcj.aopdemo.test2.IBuy.buy(..))' method='hehe'/> <aop:after pointcut='execution(* com.sharpcj.aopdemo.test2.IBuy.buy(..))' method='haha'/> <aop:after-returning pointcut='execution(* com.sharpcj.aopdemo.test2.IBuy.buy(..))' method='xixi'/> <aop:around pointcut='execution(* com.sharpcj.aopdemo.test2.IBuy.buy(..))' method='xxx'/></aop:aspect> </aop:config></beans>

這里分別定義了一個(gè)切面,里面包含四種類型的通知。

測試文件中,使用

ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext('aopdemo.xml');

來獲取 ApplicationContext,其它代碼不變。

5.3、XML 文件配置聲明切點(diǎn)

對于頻繁重復(fù)使用的切點(diǎn)表達(dá)式,我們也可以聲明成切點(diǎn)。

配置文件如下:aopdemo.xml

<?xml version='1.0' encoding='UTF-8'?><beans xmlns='http://www.springframework.org/schema/beans' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:aop='http://www.springframework.org/schema/aop' xsi:schemaLocation='http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd'> <bean class='com.sharpcj.aopdemo.test2.Boy'></bean> <bean class='com.sharpcj.aopdemo.test2.Girl'></bean> <bean class='com.sharpcj.aopdemo.test2.BuyAspectJ'></bean> <aop:config proxy-target-class='true'><aop:pointcut expression='execution(* com.sharpcj.aopdemo.test2.IBuy.buy(..))'/><aop:aspect ref='buyAspectJ'> <aop:before pointcut-ref='apoint' method='hehe'/> <aop:after pointcut-ref='apoint' method='haha'/> <aop:after-returning pointcut-ref='apoint' method='xixi'/> <aop:around pointcut-ref='apoint' method='xxx'/></aop:aspect> </aop:config></beans>5.4、XML文件配置為通知傳遞參數(shù)

BuyAspectJ.java

package com.sharpcj.aopdemo.test2;import org.aspectj.lang.ProceedingJoinPoint;public class BuyAspectJ {public String hehe(ProceedingJoinPoint pj, double price){try { pj.proceed(); if (price > 68) {System.out.println('女孩買衣服超過了68元,贈(zèng)送一雙襪子');return '衣服和襪子'; }} catch (Throwable throwable) { throwable.printStackTrace();}return '衣服'; }}

aopdemo.xml

<?xml version='1.0' encoding='UTF-8'?><beans xmlns='http://www.springframework.org/schema/beans' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:aop='http://www.springframework.org/schema/aop' xsi:schemaLocation='http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd'> <bean class='com.sharpcj.aopdemo.test2.Boy'></bean> <bean class='com.sharpcj.aopdemo.test2.Girl'></bean> <bean class='com.sharpcj.aopdemo.test2.BuyAspectJ'></bean> <aop:config proxy-target-class='true'><aop:pointcut expression='execution(String com.sharpcj.aopdemo.test2.IBuy.buy(double)) and args(price) and bean(girl)'/><aop:aspect ref='buyAspectJ'> <aop:around pointcut-ref='apoint' method='hehe'/></aop:aspect> </aop:config></beans>5.5、Xml 文件配置織入的方式

同注解配置類似,

CGlib 代理方式:

<aop:config proxy-target-class='true'> </aop:config>

JDK 代理方式:

<aop:config proxy-target-class='false'> </aop:config>六、總結(jié)

本文簡單記錄了 AOP 的編程思想,然后介紹了 Spring 中 AOP 的相關(guān)概念,以及通過注解方式和XML配置文件兩種方式使用 Spring AOP進(jìn)行編程。 相比于 AspectJ 的面向切面編程,Spring AOP 也有一些局限性,但是已經(jīng)可以解決開發(fā)中的絕大多數(shù)問題了,如果確實(shí)遇到了 Spring AOP 解決不了的場景,我們依然可以在 Spring 中使用 AspectJ 來解決。

以上就是解析Spring中面向切面編程的詳細(xì)內(nèi)容,更多關(guān)于Spring面向切面編程的資料請關(guān)注好吧啦網(wǎng)其它相關(guān)文章!

標(biāo)簽: Spring
相關(guān)文章:
主站蜘蛛池模板: 日韩成年视频 | 91极品在线 | 欧美极品欧美精品欧美视频 | 久久亚洲综合 | 国产在线精品一区 | h视频免费在线 | 91综合网| 国产99精品视频 | 亚洲成av | 欧美日韩一区二区在线 | 一区二区在线不卡 | 成人欧美一区二区三区视频xxx | 97av在线| 日韩不卡一区二区三区 | 亚洲一区二区在线 | 国产精品不卡视频 | 婷婷丁香六月天 | 国产在线视频一区二区 | 免费毛片一区二区三区久久久 | 亚洲一区二区免费视频 | 国产剧情一区二区 | 日日爽天天操 | 日韩成人影院 | 能在线观看的黄色网址 | 亚洲欧美精品一区二区三区 | 91精品国产乱码久久久久久 | 北条麻妃一区二区在线 | 欧美一区二区三区四区不卡 | 国产成人精品一区二区三区视频 | 精品一区国产 | 欧美黑人一级毛片 | 色综合天天 | 久久久久久久久综合 | 亚洲精品一区二区在线 | 色综合久久天天综合网 | 亚洲男人的天堂网站 | 粉嫩av网站 | 亚洲区在线 | 人人干人人爱 | 日韩综合网 | 亚洲日本欧美 | 国产精品综合 | 欧美亚洲一级 | 九九九久久久 | 欧美日韩综合在线 | 久久精品国产精品青草 | 久久精品毛片 | www视频在线观看 | 亚洲日本乱码在线观看 | 日韩精品免费在线视频 | 日韩欧美在线观看视频 | 日韩二三区 | 日韩免费在线 | 国产伦精品一区二区三区四区视频 | 免费黄色电影在线观看 | 国产精品久久九九 | 五月婷婷色| www久久精品 | 欧美 国产精品 | 色综合色综合 | 成年人在线视频播放 | 天天操操 | 日韩视频国产 | 国产麻豆乱码精品一区二区三区 | 伊人无码高清 | 成人av福利 | 欧美一区二区三区成人 | 免费成人毛片 | 这里只有精品视频 | 久久99精品久久久 | 久久aⅴ国产欧美74aaa | 欧美一区二区精品 | 欧美一级免费大片 | 免费一级 国产 | 精品久久久久久久久久久院品网 | 国产精品久久久久久久美男 | 欧美性一区二区 | 国产成人av一区二区 | 91伊人 | 国产精品国产a级 | 黄色一级片免费播放 | 欧美视频在线播放 | 99草草 | 一级黄色录象片 | 国产a免费| 97超碰在线播放 | 国产中文字幕在线观看 | 亚洲一级在线观看 | 国产三级精品在线 | 欧美性网 | 精品国产精品国产偷麻豆 | 成人片免费看 | 久久久99精品免费观看 | 国产精品揄拍一区二区久久国内亚洲精 | 国产无套一区二区三区久久 | 中文字幕av一区二区三区 | 国产精品美女久久久久久久久久久 | 亚洲情综合五月天 | 视频一区二区三区在线播放 | 中文一区| 国产第一区在线观看 | 日韩大片免费播放 | 国色天香成人网 | 欧美理论片在线观看 | 欧美激情一区 | 久草热8精品视频在线观看 黄色片网站视频 | 亚洲精品9999 | 人人人人人你人人人人人 | 亚洲一区中文 | av中文字幕在线播放 | 人人看人人草 | 999久久久国产999久久久 | 日韩欧美精品一区二区三区 | 毛片在线网站 | 欧美日本亚洲 | 日韩中文一区二区三区 | 97综合色 | 国产精品中文字幕在线观看 | 国产裸体bbb视频 | 国产乡下妇女做爰视频 | 一区视频 | 精品九九 | 99亚洲视频| 亚洲丶国产丶欧美一区二区三区 | 国产美女av在线 | 日本在线一区 | 色欧美日韩 | 欧美日韩三级 | 国产色婷婷精品综合在线播放 | www.久久久.com| 精品久久网 | 亚洲免费一区 | 久久久久99精品国产片 | av不卡电影在线观看 | 国产精品美女久久久久久久久久久 | a级毛片免费高清视频 | 黄色小视频网 | 久久草视频 | 欧美精品一区二区久久 | 天堂亚洲 | 男女午夜| 91精品国产综合久久婷婷香蕉 | 午夜精品在线 | 久久天堂 | 欧美精品一区二区三区蜜桃视频 | 午夜影院普通用户体验区 | 精品超碰| a级在线免费观看 | 日韩亚洲一区二区 | 男女视频在线看 | 欧美日韩免费一区二区三区 | 日本精品视频网站 | 精品国产91亚洲一区二区三区www | 国产高清在线看 | 在线国产一区 | 天天夜夜操 | 国产精品一区二区三区免费 | 国产一区二精品区在线 | 亚洲精品大片 | 久久精品国产99国产 | 99国内精品久久久久久久 | 国产精品乱码一区二区三区 | 人人射人人插 | 亚洲精品自在在线观看 | 久久九九 | 在线观看欧美成人 | 精精国产xxxx视频在线 | 蜜桃视频一区二区三区 | 久久99久久98精品免观看软件 | 在线一区二区三区 | 日韩高清成人 | 一区二区视频网站 | 亚洲 欧美 日韩 丝袜 另类 | 欧美日韩成人免费 | 成人精品视频在线观看 | av中文字幕在线播放 | 欧美日韩久久久 | 97久久香蕉国产线看观看 | 91视频分类 | 国产精品久久免费看 | 精品国产一区二区三区性色 | 可以免费看黄的网站 | 国产精品久久久久一区二区三区 | 99久久99热这里只有精品 | 成人涩涩网站 | 欧美一区中文字幕 | 免费黄色网址在线播放 | 日韩在线| 国产免费拔擦拔擦8x高清在线人 | 日韩高清国产一区在线 | 在线观看亚洲a | 国产中文字幕一区二区三区 | 欧美日本一区 | 综合伊人久久 | 午夜精品一区二区三区免费视频 | 伊人啪啪 | 夜夜爽99久久国产综合精品女不卡 | 国产精品久久嫩一区二区免费 | 亚洲97视频| 亚洲精品自拍视频 | av网站在线播放 | 精品久久99 | 欧美日韩精品亚洲 | 伊人伊人 | 一区二区免费看 | 国产大学生援交视频在线观看 | 欧美天天 | 日韩无 | 影音先锋中文字幕在线 | 亚洲一区二区三区中文字幕 | 午夜专区 | 国产一级特黄毛片在线毛片 | 草草网 | 国产精品日韩一区二区 | 成人免费crm在线观看 | 日韩精品一区二区三区中文在线 | av影片在线播放 | 久久av黄色 | 欧美一区二区三区黄色 | 国产激情在线视频 | 国产精品精品视频一区二区三区 | 久久精品国产99国产精品 | 欧美一区二区三 | 综合99| 一道本一二三区 | 成人欧美一区二区三区黑人孕妇 | 久久久精品久久 | 国内成人精品2018免费看 | 美女视频黄又黄又免费 | 亚洲欧洲精品视频在线观看 | 91精品久久久久久综合五月天 | www免费网站在线观看 | 亚洲成人精品影视 | 美女久久久 | 日韩一区二区三区av | 欧美一级在线观看 | 在线看国产 | 久久国产电影 | 互换娇妻呻吟hd中文字幕 | 亚洲成人精品在线观看 | 亚洲电影在线观看 | 亚洲精品乱码久久久久久蜜桃 | 久久久大 | 国产精品99 | 成人亚洲网站 | 91天堂在线观看 | 日韩国产在线观看 | 欧美在线二区 | 一级日韩片 | 国产一区日韩欧美 | 国偷自产一区二区免费视频 | 丁香在线 | 亚洲一区精品在线 | 亚洲成人动漫在线观看 | 精品一区二区视频 | 日韩国产一区二区三区 | 91在线精品秘密一区二区 | 中文日韩在线 | 精品999www| 99re在线播放视频 | 国产精品第2页 | 97色免费视频 | 久久国产精品久久久久久电车 | 国产精品一区二区免费 | 欧美xxxx色视频在线观看免费 | sis001亚洲原创区 | 亚洲aⅴ天堂av在线电影软件 | 九九成人 | 国产美女永久免费无遮挡 | 自拍偷拍专区 | 中文字幕一区二区三区日韩精品 | 久久久久久99 | 久草日本 | 毛片a在线| 色综合久久天天综合网 | 欧美视频精品 | 亚洲精品久久 | 欧美一级在线免费观看 | 99久久婷婷国产精品综合 | 国产黄色av | 亚洲精品免费在线 | 老牛影视av一区二区在线观看 | 盗摄精品av一区二区三区 | 国产精品高清在线 | 国产亚洲精品美女久久久久久久久久 | 国产高清不卡 | 久久久久久综合 | 亚洲伊人久久综合 | 国产一级视频 | 午夜国产精品成人 | 国产精品久久一区二区三区 | 国产欧美一区二区精品性色 | 亚洲欧美在线免费观看 | 国产三级一区二区 | 精品久久中文字幕 | 国产精品久久免费视频在线 | 中文字幕在线视频第一页 | 涩涩久久 | segui88久久综合9999 | 亚洲 中文 欧美 日韩 在线观看 | 亚洲日韩欧美一区二区在线 | 国产精品乱码一区二区三区 | 国产精品久久久久久久久岛 | 黄片毛片| 久久久中文字幕 | 精品国产欧美一区二区三区不卡 | 一级欧美 | 国产一级做a爰片在线看免费 | 国产一级影片 | 中文字幕亚洲欧美 | 欧美精品一区二 | 黄色大片网站在线观看 | 亚洲欧美一区二区三区在线 | 黄网址在线观看 | 亚洲综合无码一区二区 | 国产精品无码久久久久 | 色综合国产| 一区不卡 | 日韩一区二区不卡 | 欧美中文字幕一区 | 国产精品免费观看 | 久久精品久久精品国产大片 | 国产色区| 欧美久久久久久久久久久 | 99热婷婷| 中文字幕视频三区 | 成人免费毛片高清视频 | 开操网 | 日韩精品免费视频 | 成人三级视频网站 | 天天操天天曰 | 亚洲精久久| 欧美高清成人 | 男女羞羞视频免费观看 | 视频一区 中文字幕 | 麻豆精品国产91久久久久久 | 精品成人一区二区 | 自拍视频在线观看 | 国产高清美女一级a毛片久久 | 久久久久亚洲精品 | a级在线观看免费 | 久久久国产一区二区三区 | 亚洲精品一区二三区不卡 | 久久性| 欧美久久久久久久久久 | 欧美精品网 | 欧美视频在线免费 | 久久久久亚洲一区二区三区 | 免费黄色毛片视频 | 国产精品综合视频 | 国产大学生援交视频在线观看 | 综合网亚洲 | 黄色网址免费在线 | 精品国产乱码久久久久久88av | 精品免费国产一区二区三区四区 | 日韩av在线免费电影 | 午夜精品久久久久久久久 | 嫩草视频网 | jizz在线播放| 日本电影www | 91精品国产91久久久久久不卡 | 国产综合亚洲精品一区二 | 成人免费在线观看视频 | 一本色道精品久久一区二区三区 | 超碰激情| 精品一级| 精品国产乱码一区二区三 | 久久a国产| 日韩av一区二区三区在线 | 日本成人中文字幕在线观看 | 精品一区二区三区四区视频 | 国产美女精品一区二区三区 | 国产免费一区二区三区 | 久久久久久亚洲国产 | 污视频在线免费观看 | 九色一区 | 日韩成人中文字幕 | 国产不卡免费视频 | 久久av一区二区三区亚洲 | 日韩欧美在线不卡 | 亚洲欧美日韩国产综合 | 欧美一区二区三区免费 | 欧美在线一二三 | 天天综合永久入口 | 久久国| 色综合久久久久 | 亚洲一区二区三区免费观看 | 依人久久| 伊人伊人 | 日日日操 | 亚洲精品一区国语对白 | 成人精品视频一区二区三区 | 可以免费观看的av片 | 日本不卡免费新一二三区 | 中文字幕亚洲一区二区三区 | 国产69精品久久久久观看黑料 | 亚洲欧美激情在线 | 国产一区二区三区色淫影院 | 黄色在线视频网 | 日韩欧美视频 | 久久激情视频 | 国产一级视频 | 中文成人无字幕乱码精品 | 午夜精品久久久久久久久久久久久 | 亚洲国产精品久久人人爱 | 亚洲日韩成人 | 精品成人在线 | 中文字幕日韩欧美一区二区三区 | 久久久www | 国精产品一区二区三区 | 日韩欧美国产一区二区三区 | 97久久精品午夜一区二区 | 黄久久久 | 超碰官网| 久久a国产 | 一区二区三区四区免费观看 | 免费网站看v片在线a | 欧美精品导航 | 亚洲aⅴ| 欧美激情精品久久久久久 | 国产拍拍拍拍拍拍拍拍拍拍拍拍拍 | 日本久久久久 | 在线看一区 | 国产激情影院 | 国产999免费视频 | 久久久久久久久久久久国产精品 | 国产二区视频 | 99re在线播放视频 | 日本在线视 | 日韩久久成人 | 日韩高清一区 | 久久色av| 国产综合精品 | 国产精品乱码一二三区的特点 | 亚洲第一色片 | a在线免费观看 | 亚洲美女av在线 | 国产欧美精品区一区二区三区 | 久久精品久久久久久久久久久久久 | 精品久久久久香蕉网 | 天天干天天插 | 天天插天天操天天干 | 国产在线视频一区二区 | 国产一级毛片电影 | 日韩一级片 | 在线草| 四季久久免费一区二区三区四区 | 精品一二区 | 国产精品爱久久久久久久 | 天天综合网7799精品 | 日韩在线精品视频 | 日韩一级免费在线观看 | 中文字幕欧美日韩 | 欧美黑人一级毛片 | 91精品国产高清一区二区三区 | 国产成人精品一区二区三区视频 | 岛国一区 | 欧美精品福利视频 | 人人草视频在线观看 | 亚洲一区在线日韩在线深爱 | 欧美精品综合 | 日韩午夜视频在线观看 | 欧美日韩一区二区中文字幕 | 伊人一区 | 久久国内精品 | 日韩视频在线播放 | 天天干天天爽 | 夜夜春精品视频高清69式 | 欧美日韩一二三区 | 午夜免费观看网站 | 天天干夜干| 精品久久久久久久 | 日韩一区二区福利 | av中文字幕在线播放 | 久久精品久久久久久久久久16 | 精品一区久久 | 激情久久久| 国产精品免费观看 | 国产一级特黄aaa大片 | 婷色综合| 欧美视频精品 | 日批免费观看视频 | 欧美日韩亚洲一区二区 | 小川阿佐美88av在线播放 | 午夜影院普通用户体验区 | 久久一| 免费在线精品视频 | 黄色一级毛片 | 日韩三级在线免费观看 | 免费国产在线视频 | 久草中文在线 | 亚洲综合大片69999 | 欧美啪| 中文字幕在线三区 | 嫩草网址 | 91偷拍精品一区二区三区 | 久久久久久久久一区二区三区 | 欧美一级全黄 | 亚洲精品久久久一区二区三区 | 国产精品999 | 成人欧美 | 日韩成人一区二区 | 中文字幕av一区 | 亚洲一区二区三区视频免费观看 | 国产精品一区亚洲二区日本三区 | 国产真实精品久久二三区 | 成年人在线观看视频 | 亚洲欧美在线视频 | 一级黄色生活视频 | 91九色porny首页最多播放 | 日韩爱爱网址 | 国产亚洲一区二区三区在线观看 | 亚洲福利国产 | 天天操天天插 | 三级黄色片在线观看 | 久久人人爽人人爽 | av网站免费 | 国产日韩欧美在线 | 久久精品久久综合 | 亚洲精品在线看 | 曰批视频在线观看 | 综合99 | 亚洲在线视频 | 久在线观看 | 三级av网站 | 国产精品无 | 日韩国产欧美一区 | 亚洲福利在线观看 | 成年入口无限观看网站 | 狠狠操中文字幕 | 中文字幕一区二区三区乱码图片 | 一区二区三区影院 | 国产精品色婷婷亚洲综合看 | 精品欧美黑人一区二区三区 | 亚洲精品9999 | 国产黄色大片免费看 | 亚洲狠狠爱一区二区三区 | 精品国产成人 | 91精品一区二区 | 日韩精品中文字幕一区二区三区 | 国产精品毛片一区二区在线看 | 欧美日韩精品一区二区三区在线观看 | 日韩精品视频在线播放 | 欧美一区二区免费 | 91婷婷射 | 久久另类 | 成人在线视频免费观看 | 久久99精品久久久久国产越南 | 国产美女黄色片 | 色综合天天综合网国产成人网 | 国产综合精品 | 国产精品s色 | 99看 | 国外成人在线视频网站 | 一区二区三区av | 99成人| 91精品啪啪 | 欧美jizzhd精品欧美巨大免费 | 99热这里有精品 | av福利在线观看 | 日韩视频一区二区三区在线观看 | 日韩精品一区二区在线观看 | 日韩欧美一区二区三区 | 久久久一区二区 | 国产欧美精品一区二区色综合 | 91麻豆精品国产91久久久久久久久 | 99国产精品久久久久久久久久 | 日韩一区二区三区在线 | 久久久国产精品入口麻豆 | 国产综合久久 | 国产精品久久久久久久电影 | 日韩精品一区二区三区视频播放 | 中文字幕第66页 | 日韩三级电影在线免费观看 | a级在线免费 | 成人爽a毛片一区二区免费 美女高潮久久久 | aaa在线观看 | 欧美1级 | 中文字幕在线精品 | 中文字幕加勒比 | 国产综合亚洲精品一区二 | 日本黄色一级片视频 | 在线免费视频一区 | 久久成人国产精品 | 综合色综合 | 欧美国产日韩另类 | 黄色毛片免费看 | 日韩成人免费中文字幕 | 欧美高清dvd | 一区二区不卡视频 | 国产在线在线 | 中文字幕日韩视频 | 99亚洲视频 | 狠狠干狠狠干 | 精品无人乱码一区二区三区的优势 | 国产精品久久久久久亚洲调教 | 日韩欧美中文在线 | 国产日韩视频在线观看 | 91久久久久久久久 | www..99re| 欧美日韩一级电影 | 日韩视频在线观看一区 | 成人av网站在线观看 | 国内精品99 | 黄色国产一级视频 | 国产精品第一国产精品 | 国产精品久久久久久久久久 | 亚洲精品在线视频 | 草草草久久久 | 国产精品久久国产精品 | 91精品久久久久久久久入口 | 国产不卡精品视频 | 精品国产一区二区三区小蝌蚪 | 依人久久| 成人午夜精品一区二区三区 |