動吧加強

AOP

是一種設計思想(mvc分層架構設計思想,鏈接池池化思想,ioc控制反轉思想,oop面向對象思想),強調的是一個服務增益的思想,面向切面編程。
當咱們寫一個類,系統底層幫咱們生成一個子類,這種方法就叫作代理。如今默認是cglib代理spring

aop相關術語

切面(aspect):咱們會寫一個類,基於這個類構建的對象就是切面對象,這個類寫的時候會用@Aspect描述,用這個註解描述的類稱之爲切面類
通知(Advice):在切面某個特定的點上要執行的動做稱之爲通知
鏈接點(joinpoint):通常指向被攔截到的目標方法,就是要爲哪一個方法作擴展
好比,坐地鐵,要作安檢,安檢的動做就是通知,安檢的地方就能夠看作是切面(封裝了鏈接點和通知方法的對象),正在安檢的點就能夠看作是鏈接點,一堆安檢點就叫作切入點數據庫

配置

image

業務描述

基於項目中的核心業務,添加簡單的日誌操做,藉助SLF4J日誌API輸出目標方法的執行時長。
記錄日誌,爲了防止重複性的編寫,在方法執行前記錄一下時間,在方法結束後再記錄一下時間,時間相減就是目標方法執行時間編程

建立

首先在com.cy.pj.common.aspect包下建立SysLogAspect類
image
Aspect 註解描述的類爲spring aop中的一個切面類型,此類型能夠定義:1)切入點(PointCut)方法 (能夠是多個):要進行功能拓展的一些點
2)通知(Advice)方法 (能夠是多個):封裝了擴展功能的一個或多個方法(在切入點方法以前或以後要執行的方法)。
@Pointcut 註解描述的方法爲切入點方法,註解中定義的內容爲切入點表達式(能夠有多種形式)緩存

1)bean(bean名稱) 切入點表達式,這個表達式中的名字爲spring容器中管理的一個bean名字。
2)bean表達式是一種粗粒度的切入點表達式,這種表達式定義的切入點表示bean中的全部方法都是未來要切入擴展功能的一些方法(目標方法)。在當前應用中,sysUserServiceImpl這個名字對應的bean中全部方法的集合爲切入點。

ProceedingJoinPoint(鏈接點),鏈接點對象,此對象封裝了要執行的目標方法信息。調用目標方法,這個鏈接點是上面切入點方法其中的一個方法(正在執行的方法),只有環繞通知@Around描述的方法纔可使用ProceedingJoinPoint參數,只要是環繞,方法參數必須是Object。
@Around 描述的方法爲一個通知方法,這個通知咱們稱之爲環繞通知,能夠在目標方法執行以前或以後作服務增益。在環繞通知方法咱們能夠本身控制目標方法的調用。
在@Around註解裏使用上面的切入點就在參數中添加方法。
啓動執行,看控制檯
從客戶端發送一個請求,發送到服務器端,是springmvc中的c controller,image
這個類是SysYserServuceImpl的子類,這個是底層寫的(CGLIB
代理),最後是代理對象調用切面對象的around方法。
在yml文件添加一行配置imagetomcat

切面通知執行順序

image
在aspect包下添加SysTimeAspect方法
image服務器

練習

定義一個異常監控切面,對目標頁面方法進行異常監控,並以日誌信息的
形式輸出異常,之後能夠寫報警的
在aspect包下建立SysExceptionAspect類image架構

練習

定義一Cache相關切面,使用註解表達式定義切入點,並使用此註解對須要使用cache的業務方法進行描述部門裏的查詢方法
第一步:在annotation包下添加RequiredCache方法註解image
第二步:定義SysCacheAspect切面對象。在aspect包下添加SysCacheAspect方法image
第三步:使用@RequiredCache註解對部門查詢進行描述。imagemvc

從新添加一個需求

當把數據庫裏的數據更新或刪除的時候,cache裏要清空。
因此要在部門方法上添加一個@doClearCache註解框架

概覽

@Aspect:切面 @Pointcut:切入點 @Advice:通知方法 @JoinPoint:鏈接點 @Order:優先級異步

小節

以AOP方式記錄項目中的用戶行爲信息,並將其存儲到數據庫
能夠逆向思惟,先想怎麼存儲到數據庫

dao層

首先在SysLogDao接口添加int insertObject(SysLog entity);方法,由於當初查詢到的就是SysLog,因此如今寫也能夠這麼寫,而後寫映射文件

service層

在SysLogService接口添加void saveObject(SysLog entity);方法,

實現類

在SysLogServiceImpl類添加saveObject方法image
當訪問用戶管理要抓取日誌,因此要定義切面,在SysLogAspect類中添加將用戶行爲信息寫入到數據庫的方法saveUserLog(jp,(t2-t1)); 和saveUserLog方法image
ip須要添加一個工具類,把IPUtils類添加在utils包下。
操做名經過寫一個註解RequiredLog,註解裏添加一個String value() default "operation";,而後在SysUSerServiceImpl類中findPageObjects方法上添加@RequiredLog(value="分頁查尋")註解,那怎麼獲取操做名呢,得獲取這個註解,那怎麼獲取註解呢,須要先獲取這個方法,要想取到這個方法要先取到這個類,只有經過類的字節碼對象才能找到方法對象,經過方法對象找到註解對象,經過註解對象就能找到這個值了。因此纔有1.3,1.3.1,1.3.2,1.3.3
測試!


Aop事務

事務(Transaction)是一個業務,是一個不可分割的邏輯工做單元,基於事務能夠更好的保證業務的正確性。事務具有ACID特性

事務控制

在SysUserServiceImpl類中saveObject方法上添加@Transactional註解,就進行了回滾事務,這個對象由DataSourceTransactionManager管理,此註解也能夠定義在類上

事務傳播特性

未來但願此業務方法參與到其餘事務中執行,傳播特性設置爲Propagation.REQUIRED,但願此業務方法是種運行在一個獨立的事務,傳播特性設置爲Propagation.REQUIRES_NEW。
在SysLogServiceImpl類中saveObject方法上添加@Transactional(propagation = Propagation.REQUIRES_NEW)。


AOP 異步操做實現

假如寫日誌的操做是一個耗時的動做怎麼辦,好比在SysLogServiceImpl類中saveObject方法上添加try {Thread.sleep(1000);}catch(Exception e) {},而後啓動點擊用戶管理髮現也須要等待,說明查詢也被阻塞,能夠獲取一下線程名進行分析,在UserServiceImpl裏的查詢也獲取一下線程名,發現兩個方法是同一個線程,之後但願不能被阻塞,可讓寫日誌單獨開一個線程。方案一能夠在SysLogAspect類裏new一個線程,可是有弊端,由於大量建立線程內存很快會被耗盡,也是比較耗時。因此靠spring的異步了。

異步

首先要在啓動類添加 @EnableAsync //spring容器啓動時底層會建立線程池,他不屬於tomcat,而後在SysLogServiceImpl類上saveObject方法上添加一個@Async註解。
咱們能夠本身對spring框架提供的線程池進行一些簡易配置。Demo:image
而後在yml能夠作一些簡單的配置image


Cache操做實現

配置實現,在啓動類中添加@EnableCaching註解,而後在SysMenuServiceImpl類中findObjects方法上添加@Cacheable(value = "menuCache")//次註解描述的方法爲一個緩存切入點方法。
可是當更新時也要清緩存,因此要在updateObject方法上添加@CacheEvict(value = "menuCache",allEntries = true,beforeInvocation = false),value中的名字要相同,allEntries表示清楚全部


aop原型設計

相關文章
相關標籤/搜索