切面通俗來說,可以幫助我們簡化重複**。
我們在日常開發中,我們可能會在各個增刪改介面中記錄日誌,以便出現問題時可以及時有效地找出原因,但是系統中增刪改的介面不是乙個兩個,而是會有很多個,我們如果在所有增刪改的介面中編寫記錄日誌的**,就會導致記錄日誌的的邏輯散布於系統中的任何犄角旮旯,導致介面臃腫,介面核心功能不明確。
切面正好可以幫助我們解決這個問題,切面正如其名,好像是一把刀一樣,把所有增刪改介面中的記錄日誌的**橫向切割出來,然後存放到系統的中,系統中記錄日誌的**就只有這乙份,然後某個增刪改介面需要記錄日誌的話,就去定義切點表示式,讓切點表示式可以找到需要記錄日誌的介面,讓切面幫你做枯燥但又不得不做地記錄日誌。
前面介紹了,切點是一種規則,可以找出符合規則的連線點。
springaop只支援方法級別的**
spring借助了aspectj的知識點來定義springaop的切面
aspectj指示器
描述arg()
限制連線點匹配引數為指定型別的執行方法
@args()
限制連線點匹配引數由指定註解標註的執行方法
execution()用於匹配是連線點的執行方法
this()
限制連線點匹配aop**的bean引用為指定型別的類
target
限制連線點匹配目標物件為指定型別的類
@target()
限制連線點匹配特定的執行物件,這些物件對應的型別具有指定型別的註解
within()
限制連線點匹配指定的型別
@within()
限制連線點匹配指定註解所標註的型別(當使用springaop時,方法定義在由指定的註解所標註的類裡)
@annotation限定匹配帶有指定註解的連線點
execution(* com.wxx.*service(..))
表示匹配任意返回值,com.wxx包下, 以service為字尾的介面或類下且任意引數列表的方法
@annotation(com.wxx.log.log)
表示匹配所有使用了log註解的連線點(方法)
import org.aspectj.lang.annotation.*;
/** * @author 她愛微笑
* @date 2020/3/23
*/@aspect
public
class
testaspect
/** * 在被通知方法之後執行
*/@after
("execution(* com.wxx.*service(..))"
)public
void
aftergoodbye()
/** * 在被通知方法返回(return)時執行
*/@afterreturning
("execution(* com.wxx.*service(..))"
)public
void
returndosomething()
/** * 在被通知方法丟擲乙個異常時執行
*/@afterthrowing
("execution(* com.wxx.*service(..))"
)public
void
throwquarrel()
/** * 在被通知方法執行前後都執行,甚至可以決定被執行方法是否執行
*/@around
("execution(* com.wxx.*service(..))"
)public
void
gettogether()
}
註解
描述@after
通知方法會在目標方法返回或丟擲異常後呼叫
@afterreturning
通知方法會在目標方法返回後呼叫
@afterthrowing
通知方法會在目標方法丟擲異常後呼叫
@around
通知方法會將目標方法包裹起來
@before
通知方法會在目標方法呼叫之前執行
在上面的**中,每個註解中都有相同的切點表示式,這樣的**不夠優雅,使用@pointcut()
優化一下
import org.aspectj.lang.annotation.*;
/** * @author 她愛微笑
* @date 2020/3/23
*/@aspect
public
class
testaspect
/** * 在被通知方法之前執行
*/@before
("helloaspect()"
)public
void
beforehello()
/** * 在被通知方法之後或丟擲異常時執行
*/@after
("helloaspect()"
)public
void
aftergoodbye()
/** * 在被通知方法返回(return)後執行
*/@afterreturning
("helloaspect()"
)public
void
returndosomething()
/** * 在被通知方法丟擲乙個異常時執行
*/@afterthrowing
("helloaspect()"
)public
void
throwquarrel()
/** * 在被通知方法執行前後都執行,甚至可以決定被執行方法是否執行
*/@around
("helloaspect()"
)public
void
gettogether()
}
import org.aspectj.lang.proceedingjoinpoint;
import org.aspectj.lang.annotation.around;
import org.aspectj.lang.annotation.aspect;
import org.aspectj.lang.annotation.pointcut;
/** * @author 她愛微笑
* @date 2020/3/23
*/@aspect
public
class
test2aspect
/** * 使用環繞通知
* 環繞通知是非常強大的
*/@around
("hello2aspect()"
)public
void
log(proceedingjoinpoint joinpoint)
catch
(throwable throwable)
system.out.
println
("相當於返回通知");
}}
使用@around()
註解時,通知方法的第乙個引數必須是proceedingjoinpoint
,因為需要該物件執行目標方法或者其他操作。
@around
("hello2aspect()"
)public
void
log(proceedingjoinpoint joinpoint)
spring AOP 多個切面
切面 日誌 author w7 public class logger 切面 安全框架 author w7 public class security 切面 許可權 author w7 public class privilege public void setaccess string acces...
spring aop 切面測試
spring 配置 aop 切面類 package com.changhang.urgoo.impl.utils import com.changhang.urgoo.impl.entity.result.mesresult import com.changhang.urgoo.impl.entit...
Spring aop 切面程式設計
package cn.annals.demo.proc.aop import org.aspectj.lang.joinpoint import org.aspectj.lang.proceedingjoinpoint import org.aspectj.lang.annotation.after...