漫談AOP開發之初探AOP及AspectJ的用法


一、為什么需要AOP技術

AOP 是一個很成熟的技術。
假如項目中有方法A、方法B、方法C……等多個方法,
如果項目需要為方法A、方法B、方法C……這批方法增加具有通用性質的橫切處理。
 
下圖可以形象的說明具有通用性質的橫切處理的思想:
Spring AOP開發漫談之初探AOP及AspectJ的用法 - 月上西樓 - 月上西樓
在以前傳統的做法是

 

1、先定義一個Advice方法,該方法實現這個通用性質的橫切處理。
2、打開方法A、方法B、方法C……的源代碼修改,使得方法A、方法B、方法C……去調用Advice方法。
客戶電話: 為每個方法都增加日志。
客戶電話: 為每個方法前都增加權限控制。
客戶電話: 為每個方法都加……
….
如果使用AOP,可以做到程序員無需修改方法A、方法B、方法C……,但又可以為方法A、方法B、方法C增加調用Advice方法。
 
面向切面編程(AOP)是作為面向對象編程(OOP)的補充:
AOP框架具有如下兩個特征:
1、各步驟之間的良好隔離性。
2、源代碼無關性。

二、AOP的功能

保證程序員不修改方法A、方法B、方法C……的前提下,可以為方法A、方法B、方法C……增加通用處理。
AOP的本質:依然要去【修改】方法A、方法B、方法C……
—— 只是這個修改由AOP框架完成,程序員不需要改。
AOP要求去修改,到底怎么去修改方法A、方法B、方法……
AOP的實現方式有兩種:
  1. AOP框架在編譯階段,就對目標類進行修改,得到的class文件已經是被修改過的。生成靜態的AOP代理類(生成*.class文件已經被改掉了,需要使用特定的編譯器)。以AspectJ為代表 —— 靜態AOP框架。
  2. AOP框架在運行階段,動態生成AOP代理(在內存中動態地生成AOP代理類),以實現對目標對象的增強。它不需要特殊的編譯器。以Spring AOP為代表。—— 動態AOP框架。
上面兩種,哪種性能更好?很明顯靜態的AOP框架更好。
下面我們進入AspectJ的學習

三、實戰AspectJ

AspectJ是一個基於Java語言的AOP框架,提供了強大的AOP功能,其他很多AOP框架都借鑒或采納其中的一些思想。

1、下載和安裝AspectJ

    1)運行、下載得到的安裝JAR包。

 

 

在命令行窗口啟動下載得到的jar文件:java -jar aspectj-1.6.10.jar,在彈出的安裝界面會先讓你選擇Java,選擇你安裝的Java目錄      即可。將該軟件(絕對綠色)安裝到指定目錄下(筆者安裝在C盤)。

 

 

    2) 系統還應該將C:\Java\aspectj1.6\bin路徑添加到PATH環境變量中,

 

 

將C:\Java\aspectj1.6\lib\aspectjrt.jar和aspectjtools.jar添加到 CLASSPATH環境變量中。

 

 

成功安裝了AspectJ之后,將會在E:\Java\AOP\aspectj1.6路徑下(AspectJ的安裝路徑)看到如下文件結構:
  • bin:該路徑下存放了aj、aj5、ajc、ajdoc、ajbrowser等命令,其中ajc命令最常用,它的作用類似於javac,用於對普通Java類進行編譯時增強。
  • docs:該路徑下存放了AspectJ的使用說明、參考手冊、API文檔等文檔。
  • lib:該路徑下的4個JAR文件是AspectJ的核心類庫。
  • 相關授權文件。
打開DOS窗口,輸入ajc命令,可以看到輸出ajc命令的所有信息,即可知安裝和環境變量配置成功:

 

2、使用AspectJ

接下來我們模擬一個普通程序:
UserService:

package com.mybry.aop.service;
public class UserService{
public int addUser(){
System.out.println("模擬添加用戶的方法。");
return 20;
}
public void validateLogin(){
System.out.println("驗證用戶登錄。");
}
}

BookServce:

package com.mybry.aop.service;
public class BookService{
public int addBook(String name,int price){
System.out.println("正在添加圖書,書名是:"+name+",價格是:"+price);
return 100;
}
}

編譯運行結果:
Spring AOP開發漫談之初探AOP及AspectJ的用法 - 月上西樓 - 月上西樓
這兩個類正好相當於我們的方法A,方法B.....
 
假如客戶現在要求在每個方法前面增加權限檢查功能,那么該如何做呢?下面我們就是用AspectJ來實現這個功能。
現在我們在這個模擬程序基礎上增加這個AOP功能:
我們先寫一個權限檢查的Aspectj類:

 

實例1,AuthAspect:

package com.mybry.aop.aspectj;
public aspect AuthAspect{
// Advice
// execution(* com.mybry.aop.service.*.*(..)執行 任意返回值 改包下的任意類的任意方法形參不限
before():execution(* com.mybry.aop.service.*.*(..)){
// 對原來方法進行修改、增強。
System.out.println("----------模擬執行權限檢查----------");
}
}

注意這個類色聲明類型:aspect,沒錯,這是寫Aspect必須聲明的類型,只有AspectJ編譯器可以識別。
再用duni>ajc –d *.java命令編譯執行:
Spring AOP開發漫談之初探AOP及AspectJ的用法 - 月上西樓 - 月上西樓
太開心了,搞定了!
 
假如此時客戶又要求在每個方法中增加事物處理呢?也好辦,下面是事物處理類:
實例1,TxAspect:

package com.mybry.aop.aspectj;
public aspect TxAspect{
//around的意思就是在方法的前面和后面都加
Object around():execution(* com.mybry.aop.service.*.*(..)){
// 對原來方法進行修改、增強。
System.out.println("====模擬開啟事務====");
Object rvtVal = proceed();
System.out.println("====模擬結束事務====");
return rvtVal;
}
}

好了,我們再來編譯運行它:
Spring AOP開發漫談之初探AOP及AspectJ的用法 - 月上西樓 - 月上西樓
OK!我們的Aspect AOP程序到此為止!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM