相關概念
簡單例子aspect:切面,橫切多層面的關注點的模組化
joinpoint:連線點.程式執行期間的乙個點,連線點總是代表乙個方法的執行.
advice:通知, 在特定連線點處採取的行動.包括before,after,around等.
pointcut:切入點.定義乙個類似正則的表示式,與通知相關聯.
專案為springboot專案,jdk1.8,工具idea
**上的注釋,是在測試包含所有通知下測的結果,實際開發中是不會都用到的,最多的是around,功能比較強大.
首先新增依賴:
org.springframework.boot
spring-boot-starter-aop
1.5.9.release
定義乙個切面:
@aspect //宣告切面
@component //交給spring管理
public class aspecthandler
/*** 前置增強
* 當沒有around時,先執行before, 走after,遇到異常,然後afterthrowing,
* 如果沒有異常走afterreturning,在這裡可以看到返回值
*/@before("pointcut()") //通知型別的一種,所關聯的切入點表示式是pointcut方法
public void dobeforetest(joinpoint point)
/*** 後置增強,方法退出時執行
*/@afterreturning(returning = "ret",pointcut = "pointcut()")
public void doafterreturning(joinpoint point,object ret)
/*** 最終(final)增強,不管方法退出還是丟擲異常都會執行
*/@after("pointcut()")
public void doafter(joinpoint point)
/*** 異常增強
*/@afterthrowing(throwing = "ex",pointcut = "pointcut()")
public void doafterthrowing(joinpoint point,exception ex)
/*** 環繞增強
* 當around存在的時候,首先執行.再before,如果遇到異常,執行after方法,走afterthrowing結束.
* 當around存在的時候,首先執行.再before,再執行after方法,沒有異常然後afterreturning方法
*/@around("pointcut()")
public object doaround(proceedingjoinpoint point) throws throwable
}service層**: 當某乙個類的方法符合pointcut表示式,就是在idea左邊顯示相對應的小圖示
controller層就不貼出來了,直接呼叫就好;
在沒個通知打上斷點,可以觀察執行的順序以及引數值,也就是連線點的內容
其中包含了**物件,目標物件,方法,引數,動態匹配到的方法等等都可以檢視到.
乙個簡單的例子就完成了. 這樣我們就可以使用它去記錄日誌,快取等等.
**1:
(一)aop**實現有兩種方法:
1:預設使用標準jdk動態**,這使得任何介面都可以被**.
2:也可以使用cglib**,如果業務物件沒有實現介面,就預設cglib,也可以強制使用.但是有一些問題需要考慮(下圖給出官方描述):
1️⃣就是說不能用final修飾類,否則無法覆蓋;
2️⃣在spring3.2中,不再需要將cglib新增到專案類路徑,spring核心jar已經包含,這就意味著,基於cglib**支援,工作方式相同,jdk動態**總是有的.
3️⃣**構造器會被呼叫兩次.
(二)@aspect註解對於類路徑中的自動檢測是不夠的,所以還需要新增單獨的@component
(三)切入點表示式和切入點簽名:
@pointcut("execution(* com.surd.aopdemo.service..*.*(..))") //切入點表示式
private void pointcut() {} //切入點簽名
(四)支援的切入點指示符:
execute: 常用, 方法匹配
@annotation: 註解匹配;(限制匹配連線點的地方有給定的註解)
within:限制匹配某些型別內的連線點(只需執行在匹配型別中宣告的方法)
@within:在具有給定註解的型別內部限制匹配連線點(執行使用給定註解的型別中宣告的方法)
args: 限制匹配連線點,其中引數是給定型別的例項
@args:限制匹配連線點,實際引數的執行時型別有給定型別的註解
更詳細的描述,還有很多指示符,請參考官方文件:
切入點表示式:
切入點表示式可以使用&&, ||,!進行組合.也可以通過名稱來引用切入點表示式.以下**摘自官網:
//匹配任何公共方法
@pointcut(「execution(public * *(..))」)
private void anypublicoperation(){}
//匹配交易模組中的方法
private void intrading(){}
//匹配交易模組中額任何公共方法
@pointcut(「anypublicoperation()&& intrading()」)
private void tradingoperation(){}
表示式格式:execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern)
throws-pattern?)
() : 表示匹配乙個不帶引數的方法;
(..): 表示匹配任意數量的引數(0個或者多個);
(*): 表示任意型別的乙個引數的方法;
(*,string):表示匹配乙個方法採用兩個引數,第乙個是任意型別,第二個必須是string型別;
* : 匹配任意字元,但只能匹配乙個元素
.. : 匹配任意字元,可以匹配任意多個元素,表示類時,與*聯合使用
+ : 必須跟在類名後面,表示類本身和整合或者擴充套件指定類的所有類
joinpoint:
該介面提供了許多有用的方法如:
getargs(): 返回方法引數
getthis(): 返回**物件
gettarget(): 返回目標物件
getsignature(): 返回正在被通知的方法的描述
……
暫時寫到這裡;
小結:
1️⃣: spring aop是基於**的(jdk動態**和cglib);
2️⃣: 開發中只需要專注於業務功能,像日誌這一類功能可以提取出來使用此類方法處理;
3️⃣: 根據應用中實際情況來定義粗粒度,細粒度的切入點,處理不同的需求;
更多詳情參考spring aop:
Springboot中加入druid連線池
目錄 druid是阿里巴巴開發的號稱為監控而生的資料庫連線池,druid是目前最好的資料庫連線池。在功能 效能 擴充套件性方面,都超過其他資料庫連線池,同時加入了日誌監控,可以很好的監控db池連線和sql的執 況。jd連線資料庫的url mysql jdbc mysql localhost 3306...
spring boot 七 隨機埠
學習文章 springboot小技巧 為spring cloud的應用實用隨機埠非常簡單,主要有兩種方法 設定server.port 0,當應用啟動的時候會自動的分配乙個隨機埠,但是該方式在註冊到eureka的時候會乙個問題 所有例項都使用了同樣的例項名 如 lenovo test hello se...
(七)SpringBoot嵌入式Servlet
修改 yml檔案 server.port等 編寫乙個embeddedservletcontainercustomizer 嵌入式的servlet容器定製器,來修改servlet容器配置 監聽servletcontext啟動初始化 override public void contextinitial...