AOP之AspectJ框架的使用

AOP之AspectJ框架的使用

本文轉自:http://www.cnblogs.com/whgk/p/6627187.html

前面講解了spring的特性之一,IOC(控制反轉),因為有了IOC,所以我們都不需要自己new對象了,想要什麼,spring就給什麼。而今天要學習spring的第二個重點,AOP。一篇講解不完,所以這篇文章主要介紹一下什麼是AOP,如何去理解AOP。理解完之後,在spring中如何使用AspectJ AOP框架的。看得懂,寫的出spring配置的那麼就學的差不多了。加油。建議都自己手動實現一遍,這樣才能更好的理解。

--WH

一、什麼是AOP?

AOP:面向切面編程,採用橫向抽取機制,取代了傳統的縱向繼承

IOC:控制反轉

跟IOC一樣,我也不知道,這麼高大上的名稱,被嚇壞了,MD,但是通過前面一節的學習,IOC不就是讓spring給我們new對象嗎,而不需要我們自己創建,

而AOP是一種面向切面的思想,但是我們平常說的spring使用了AOP,實際上說的是spring實現AOP思想的底層原理,而底層原理就是使用動態代理來增強某個方法。所以平常說AOP技術實際上就是指通過動態代理來對方法進行增強。

比如:我們需要對一個已經寫好的類中的方法進行增強,在不改動該類方法的代碼的情況下,如何做呢?

傳統縱向繼承

編寫一個類,繼承該類,重寫該類中的這種需要增強的方法,這樣確實可以達到我們的目的,但是一旦需要修改的方法所屬的類不是一個類,那麼就需要在多寫很多子類,增加很多方法,編程量就是一個很大的問題,並且後期要修改,工作量也很大。

AOP之AspectJ框架的使用

橫向抽取機制,將要增強所用到的代碼提取到一個類中,然後對需要增強的方法通過代理類去將其增強即可。

AOP之AspectJ框架的使用

二、動態代理的兩個方式

JDK動態代理。接口+實現類

cglib字節碼增強。 實現類

為了更好的理解spring的AOP技術,我們應該手動編寫以上兩種實現動態代理的方法,然後才能體會到spring實現AOP技術所帶來的便利。

2.1、JDK動態代理。

要使用JDK動態代理的類,必須要有接口。這是前提條件。

AOP之AspectJ框架的使用

編寫UserService接口和UserServiceImpl。

AOP之AspectJ框架的使用

創建代理類的工廠proxyFactory

AOP之AspectJ框架的使用

增強代碼的類

AOP之AspectJ框架的使用

測試testApp

AOP之AspectJ框架的使用

測試結果 成功增強了userServiceImpl對象的add方法。如果別的類有需要被增強的方法,那麼同樣通過創建工廠代理就可以拿到對應的代理對象。然後進行加強

AOP之AspectJ框架的使用

2.2、cglib動態代理。

被代理的對象不需要在實現接口,要求就放鬆了很多。很多時候都採用cglib來進行動態代理。

需要導入兩個jar包

AOP之AspectJ框架的使用

spring已經將cglib和asm整合到了spring-core-3.2.0.jar中,所以我們導入spring的jar包就不需要在重複導這兩個包了。

跟JDK動態代理的編寫流程是一樣的

UserServiceImpl。沒有接口了

AOP之AspectJ框架的使用

增強方法的類

AOP之AspectJ框架的使用

創建代理的工廠(和jdk動態代理有區別)

AOP之AspectJ框架的使用

測試

成功增強方法。

注意:CGLib採用了非常底層的字節碼技術,其原理是通過字節碼技術為一個類創建子類,並在子類中採用方法攔截的技術攔截所有父類方法的調用,順勢織入橫切邏輯,所以 說被代理的類不能有final關鍵字

三、spring中使用AOP的相關術語

3.1、Target:目標類,需要被增強的類,也就是上面我們寫的UserServiceImpl。

3.2、JointPoint:連接點,目標類上需要被增強的方法,(這些方法可以被增強,也可以不增強,也就是說目標類中所有的方法都可以稱為是連接點)

3.3、PointCut:切入點,被增強的方法(已經確定這個方法要被增強),切入點就是一個連接點的子集

3.4、Advice:增強/通知,增強的代碼,也就是上面將增強的代碼湊成的一個類。類中的每個方法都代表一個增強的功能代碼,這個類中的方法就被稱為通知

3.5、weaving:織入,將切入點和通知結合,從沒被增強到已經增強的過程

3.6、Aspect:切面,切入點和通知結合,切入點 和 通知點 多點形成面 特殊情況:一個切入點 和 一個通知

畫張圖就可以理解了。

AOP之AspectJ框架的使用

3.7、Introduction(引介) 特殊的通知,可以對類增強,添加方法或字段。(知道)

四、spring如何幫我們實現AOP技術(初級版)

spring創建代理工廠bean,屬於半自動,思路跟我們用JDK動態代理和cglib動態代理是一樣的,只是spring通過ioc幫我們創建這些對象,工廠也是由spring提供。唯一的不同是,我們編寫的通知類(之後將其叫成切面類,也就是放增強的代碼方法的類) 必須實現MethodInterceptor(注意導包時的問題,這個名稱跟cglib中的那個一樣,不要導錯了)接口,並實現invoke方法,這裡就是編寫如何增強切入點,好比上面jdk動態代理和cglib代理中的匿名內部類中的方法一樣。具體下面講解。

導入jar包

AOP之AspectJ框架的使用

spring : 4個核心 + 1個依賴

spring aop聯盟:

AOP之AspectJ框架的使用

spring aop 實現:

AOP之AspectJ框架的使用

UserServiceImpl

AOP之AspectJ框架的使用

MySpect 切面類,

AOP之AspectJ框架的使用

applicationcontext.xml。

AOP之AspectJ框架的使用

這裡注意,如果沒有接口,那麼其中必須使用3.4的代碼也就是34行的代碼,必須告訴spring,使用cglib進行代理,否則出錯。

測試

AOP之AspectJ框架的使用

 

總結:這種方式屬性半自動的,需要配置工廠bean,並且目標類的確定太小了,每次只能指定一個目標類,如果我們想對別的類也進行加強,那麼就需要在工廠bean中又配置一個目標類,這就體現不出spring的優勢了。不推薦使用這種。瞭解整個發展過程即可

五、spring實現AOP技術(中級 掌握)

全自動過程。直接覆蓋很多目標類,不需要在一個個對目標類進行編寫通知和工廠了。

其他都一樣,配置文件不一樣。切入點就不單單是一個目標類了。而是一個範圍。

AOP之AspectJ框架的使用

切面類還是跟上面一樣

AOP之AspectJ框架的使用

測試: 成功

AOP之AspectJ框架的使用

總結:相比初級的aop實現,好的地方在不用在自己設置工廠bean了,還在直接大範圍的指定代理目標類,而不是一個類只能被指定一次。這就是全自動,不用我們配置工廠bean

,spring幫我們都做好了。我們只需要關注切面類,也就是通知和切入點的結合即可。

六、使用AspectJ框架(xml方式)實現aop(高級,推薦)

使用這個的好處在於,我們都不需要在切面類中實現什麼通知類型接口了,通知類型接口也在配置文件中編寫,而切面類只要關注增強的方法代碼即可。並且不管業務類是否實現接口,編寫的代碼都是一樣的,如果實現了接口。AspectJ框架會使用jdk代理,如果沒有實現接口,則使用cglib代理,這兩者之間相互轉換。而spring內置的aop技術則需要自己手動去設置,默認是jdk,如果沒有接口,不會自動幫我們轉換。

導包:新增兩個aspect支持的jar包

aop聯盟:com.springsource.org.aopalliance-1.0.0.jar

spring aop支持:spring-aop-3.2.0.RELEASE.jar

aspect 規範:com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar

spring aspect 支持:spring-aspects-3.2.0.RELEASE.jar

AOP之AspectJ框架的使用

AspectJ規定通知類型

6個,知道5個,掌握一個

1.before:前置通知(應用:各種校驗)

在方法執行前執行,如果通知拋出異常,阻止方法運行

2.afterReturning:後置通知(應用:常規數據處理)

方法正常返回後執行,如果方法中拋出異常,通知無法執行

必須在方法執行後才執行,所以可以獲得方法的返回值。

3.around:環繞通知(應用:十分強大,可以做任何事情) 【掌握】

方法執行前後分別執行,可以阻止方法的執行。要求必須手動的執行目標方法。

4.afterThrowing:拋出異常通知(應用:包裝異常信息)

方法拋出異常後執行,如果方法沒有拋出異常,無法執行

5.after:最終通知(應用:清理現場)

方法執行完畢後執行,無論方法中是否出現異常

配置文件

AOP之AspectJ框架的使用

通知類型的詳解

AOP之AspectJ框架的使用

AOP之AspectJ框架的使用

切面類

AOP之AspectJ框架的使用

測試:

AOP之AspectJ框架的使用

總結:使用AspectJ框架實現AOP,好處很多,關注的點只有切面類(不需要實現通知類型接口),切入點範圍,還有通知類型。所以在配置文件中,也只需要配置這三個關鍵的東西即可,具體看上面的配置文件

七、使用AspectJ框架(註解方式)實現aop(高級,推薦)

使用註解的話,很簡單,就是把xml方式用註解給替代,其中也就做6件事

1、將切面類配置給spring,相當於

@component

2、將切面類申明為切面

@Aspect

AOP之AspectJ框架的使用

3、將目標類配置給spring

@component 如何不編寫名稱的話,那麼要獲取該對象,則使用userServiceImpl進行獲取。

AOP之AspectJ框架的使用

4、申明目標類切入點範圍

1.方法必須private,沒有返回值,沒有參數

2.之後使用將其當成方法調用。例如:@After("myPointcut()")

@Pointcut("execution(* com.wuhao.aspectj.annotation.*.*(..))")

AOP之AspectJ框架的使用

5、編寫相應的通知

@Before 前置

@AfterReturning 後置,可以獲得返回值,必須在註解中確定返回值參數名稱。

@AfterThrowing 拋出異常,可以獲得具體異常信息,必須在註解確定第二個參數名稱

@Around 環繞[]

@After 最終

AOP之AspectJ框架的使用

6:必須在xml中掃描註解和啟用aop

AOP之AspectJ框架的使用

7、測試

AOP之AspectJ框架的使用

總結;註解的編寫也很簡單,要會寫註解,首先的知道xml是如何實現的,然後一步步用註解來替代xml的內容即可。並且要知道使用AspectJ框架需要配置哪些內容,就三個點,

xml:

目標類bean

切面類bean

//切面

//切入點範圍:

//通知類型:

八、總結

基本上把spring中使用AOP的技術講清楚了,可能一開始很不習慣,用多了自然就習慣了,並且建議手寫你jdk代理和cglib代理,這樣一步步來,就更容易理解在spring中應用AOP的技術的編寫代碼了。


分享到:


相關文章: