大战熟女丰满人妻av-荡女精品导航-岛国aaaa级午夜福利片-岛国av动作片在线观看-岛国av无码免费无禁网站-岛国大片激情做爰视频

Spring框架教程
Spring IOC控制反轉
Spring AOP面向切面編程
Spring集成MyBatis
Spring事務
Spring與Web

AspectJ對AOP的實現

對于 AOP 這種編程思想,很多框架都進行了實現。Spring 就是其中之一,可以完成面向切面編程。然而,AspectJ 也實現了 AOP 的功能,且其實現方式更為簡捷,使用更為方便,而且還支持注解式開發。所以,Spring 又將 AspectJ 的對于 AOP 的實現也引入到了自己的框架中。

在 Spring 中使用 AOP 開發時,一般使用 AspectJ 的實現方式。

AspectJ 簡介

AspectJ 是一個面向切面的框架,它擴展了 Java 語言。AspectJ 定義了 AOP 語法,它有一個專門的編譯器用來生成遵守 Java 字節編碼規范的 Class 文件。

官網地址:http://www.eclipse.org/aspectj/

AspetJ 是 Eclipse 的開源項目,官網介紹如下:

a seamless aspect-oriented extension to the Javatm programming language(一種基于 Java 平臺的面向切面編程的語言)

Java platform compatible(兼容 Java 平臺,可以無縫擴展)

easy to learn and use(易學易用)

AspectJ 的通知類型

AspectJ 中常用的通知有五種類型:

● 前置通知

● 后置通知

● 環繞通知

● 異常通知

● 最終通知

 

AspectJ 的切入點表達式

AspectJ 定義了專門的表達式用于指定切入點。表達式的原型是:

execution ( [modifiers-pattern] 訪問權限類型

ret-type-pattern 返回值類型

[declaring-type-pattern] 全限定性類名

name-pattern(param-pattern)方法名(參數名)

[throws-pattern] 拋出異常類型

)

切入點表達式要匹配的對象就是目標方法的方法名。所以,execution 表達式中明顯就是方法的簽名。注意,表達式中加[ ]的部分表示可省略部分,各部分間用空格分開。在其中可以使用以下符號:

舉例:

● execution(public * *(..))

指定切入點為:任意公共方法。

● execution(* set*(..))

指定切入點為:任何一個以“set”開始的方法。

● execution(* com.xyz.service.*.*(..))

指定切入點為:定義在 service 包里的任意類的任意方法。

● execution(* com.xyz.service..*.*(..))

指定切入點為:定義在 service 包或者子包里的任意類的任意方法。“..”出現在類名中時,后面必須跟“*”,表示包、子包下的所有類。

● execution(* *.service.*.*(..))

指定只有一級包下的 serivce 子包下所有類(接口)中所有方法為切入點

● execution(* *..service.*.*(..))

指定所有包下的 serivce 子包下所有類(接口)中所有方法為切入點

● execution(* *.ISomeService.*(..))

指定只有一級包下的 ISomeSerivce 接口中所有方法為切入點

● execution(* *..ISomeService.*(..))

指定所有包下的 ISomeSerivce 接口中所有方法為切入點

●  execution(* com.xyz.service.IAccountService.*(..))

指定切入點為:IAccountService 接口中的任意方法。

● execution(* com.xyz.service.IAccountService+.*(..))

指定切入點為:IAccountService 若為接口,則為接口中的任意方法及其所有實現類中的任意方法;若為類,則為該類及其子類中的任意方法。

● execution(* joke(String,int)))

指定切入點為:所有的 joke(String,int)方法,且 joke()方法的第一個參數是 String,第二個參數是 int。如果方法中的參數類型是 java.lang 包下的類,可以直接使用類名,否則必須使用全限定類名,如 joke( java.util.List, int)。

● execution(* joke(String,*)))

指定切入點為:所有的 joke()方法,該方法第一個參數為 String,第二個參數可以是任意類型,如joke(String s1,String s2)和joke(String s1,double d2)都是,但joke(String s1,double d2,Strings3)不是。

● execution(* joke(String,..)))

指定切入點為:所有的 joke()方法,該方法第一個參數為 String,后面可以有任意個參數且參數類型不限,如 joke(String s1)、joke(String s1,String s2)和 joke(String s1,double d2,String s3) 都是。

● execution(* joke(Object))

指定切入點為:所有的 joke()方法,方法擁有一個參數,且參數是 Object 類型。joke(Object ob)是,但,joke(String s)與 joke(User u)均不是。

● execution(* joke(Object+)))

指定切入點為:所有的 joke()方法,方法擁有一個參數,且參數是 Object 類型或該類的子類。不僅 joke(Object ob)是,joke(String s)和 joke(User u)也是。

 

AspectJ 的開發環境

1、導入三個 Jar 包

● spring 框架 aop 的實現 jar 包: spring-aop.jar

● aspectj 框架對 aop 的實現 jar 包: aspectjrt.jar , aspectjweaver.jar

● Spring 對 AOP 的實現包在 Spring 框架的解壓包中:spring-aop-4.3.9.RELEASE.jar

AspectJ 自身的 Jar 包:在 AspectJ 官網下載:

http://www.eclipse.org/aspectj/downloads.php

下載后的 aspectj-1.9.0.jar ,解壓目錄:

2、引入 AOP 約束

在配置文件頭部,要引入關于 aop 的約束。在 Spring 框架的解壓目錄中,\docs\spring-framework-reference\html 下的 xsd-configuration.html 文件中。

在前面 Spring 實現 AOP 時,并未引入 AOP 的約束,而在 AspectJ 實現 AOP 時,才提出要引入 AOP 的約束。說明,配置文件中使用的 AOP 約束中的標簽,均是 AspectJ 框架使用的,而非 Spring 框架本身在實現 AOP 時使用的。

AspectJ 對于 AOP 的實現有注解和配置文件兩種方式,常用是注解方式。

AspectJ 基于注解的 AOP 實現

AspectJ 提供了以注解方式對于 AOP 的實現。

1、實現步驟

Step1:定義業務接口與實現類

Step2:定義切面 POJO 類

該類為一個 POJO 類,將作為切面出現。其中定義了若干普通方法,將作為不同的通知方法。

Step3:在切面類上添加@Aspect 注解

在定義的 POJO 類上添加@Aspect 注解,指定當前 POJO 類將作為切面。

 

Step4:在 POJO 類的普通方法上添加通知注解

切面類是用于定義增強代碼的,即用于定義增強目標類中目標方法的增強方法。這些增強方法使用不同的“通知”注解,會在不同的時間點完成織入。當然,對于增強代碼,還要通過 execution 表達式指定具體應用的目標類與目標方法,即切入點。

 Step5:注冊目標對象與 POJO 切面類

 Step6:注冊 AspectJ 的自動代理

在定義好切面 Aspect 后,需要通知 Spring 容器,讓容器生成“目標類+ 切面”的代理對象。這個代理是由容器自動生成的。只需要在 Spring 配置文件中注冊一個基于 aspectj 的自動代理生成器,其就會自動掃描到@Aspect 注解,并按通知類型與切入點,將其織入,并生成代理。

的底層是由 AnnotationAwareAspectJAutoProxyCreator 實現的。

從其類名就可看出,是基于 AspectJ 的注解適配自動代理生成器。

其工作原理是,通過掃描找到@Aspect 定義的切面類,再由切面類根據切入點找到目標類的目標方法,再由通知類型找到切入的時間點。

Step7:測試類中使用目標對象的 id

舉例:aop_aspectj 項目的 annotation 包

2、@Before 前置通知-方法有 JoinPoint 參數

在目標方法執行之前執行。被注解為前置通知的方法,可以包含一個 JoinPoint 類型參數。該類型的對象本身就是切入點表達式。通過該參數,可獲取切入點表達式、方法簽名、目標對象等。

不光前置通知的方法,可以包含一個 JoinPoint 類型參數,所有的通知方法均可包含該參數。

3、@AfterReturning 后置通知-注解有 returning 屬性

在目標方法執行之后執行。由于是目標方法之后執行,所以可以獲取到目標方法的返回值。該注解的 returning 屬性就是用于指定接收方法返回值的變量名的。所以,被注解為后置通知的方法,除了可以包含 JoinPoint 參數外,還可以包含用于接收返回值的變量。該變量最好為 Object 類型,因為目標方法的返回值可能是任何類型。

4、@Around 環繞通知-增強方法有 ProceedingJoinPoint 參數

在目標方法執行之前之后執行。被注解為環繞增強的方法要有返回值,Object 類型。并且方法可以包含一個 ProceedingJoinPoint 類型的參數。接口 ProceedingJoinPoint 其有一個proceed()方法,用于執行目標方法。若目標方法有返回值,則該方法的返回值就是目標方法的返回值。最后,環繞增強方法將其返回值返回。該增強方法實際是攔截了目標方法的執行。

 

5、@AfterThrowing 異常通知-注解中有 throwing 屬性

在目標方法拋出異常后執行。該注解的 throwing 屬性用于指定所發生的異常類對象。

當然,被注解為異常通知的方法可以包含一個參數 Throwable,參數名稱為 throwing 指定的名稱,表示發生的異常對象。

6、 @After 最終通知

無論目標方法是否拋出異常,該增強均會被執行。

7、@Pointcut 定義切入點

當較多的通知增強方法使用相同的 execution 切入點表達式時,編寫、維護均較為麻煩。AspectJ 提供了@Pointcut 注解,用于定義 execution 切入點表達式。

其用法是,將@Pointcut 注解在一個方法之上,以后所有的 executeion 的 value 屬性值均可使用該方法名作為切入點。代表的就是@Pointcut 定義的切入點。這個使用@Pointcute 注解的方法一般使用 private 的標識方法,即沒有實際作用的方法。

   

全部教程
主站蜘蛛池模板: 精品综合一区二区三区 | 亚洲国产精品视频在线观看 | 露脸真实国产精品自在 | 在线 | 一区二区三区 | 五月激情五月婷婷 | 久久国产精品老人性 | 一 级做人爱全视频在线看 一a级毛片 | 久久成人动漫 | 国产一级淫片a视频免费观看 | 中文字幕综合网 | 综合伊人| 久久亚洲不卡一区二区 | 天天操天天操天天操 | 国产你懂得 | 一级毛片牲交大片 | 午夜影院0606 | 日本不卡免费新一区二区三区 | 二性视频 | 国产美女久久久久 | 日韩一级视频免费观看 | 国产日韩欧美中文字幕 | 色综合天天综合网站中国 | 大尺度视频网站久久久久久久久 | 国产亚洲精品自在久久77 | 欧美成人久久一级c片免费 欧美成人剧情中文字幕 | 在线中文字幕观看 | 口国产成人高清在线播放 | 福利社看片 | 国产舐足视频在线观看 | 手机看片日韩国产一区二区 | 国内精品视频一区 | 激情在线观看视频 | www.日韩视频| 男人天堂网在线观看 | 日韩亚洲欧美在线观看 | 精品久久久久久免费影院 | 毛片在线高清免费观看 | 国产精品在线播放 | 亚洲精品一区二区久久这里 | 国产视频2021 | 色综合久久天天综合观看 |