javascript
Spring AOP 应用篇
添加依賴
使用Spring AOP必須添加AOP的依賴包,并配置AOP
- Spring MVC中添加并配置 AOP
- 在Maven中添加AOP依賴
- 在spring-MVC配置文件中,添加配置
- Spring Boot添加并配置AOP
由于用的是SpringBoot,所以也不需要配置aop
切面表達式
概覽
匹配包/類型
within()
// 匹配service類里頭的所有方法 @Pointcut("within(com.test.service)") public void matchType(){}// 匹配com.test包及子包下所有類的方法 @Pointcut("within(com.test..*)" public void matchPackage(){} 復制代碼匹配注解
@annotation()
/*** @annotation 匹配方法級別* 如下,匹配 標注有 @ToExcel注解 的方法*/ @Pointcut("@annotation(com.demo.security.ToExcel)") public void annotation(){} 復制代碼@within()
/*** @within 匹配類級別* 非 Spring環境下,要求的 annotation 的 RetentionPolicy 級別為 CLASS* 如下,匹配 標注有 @Service注解 的類 的所有方法*/ @Pointcut("@within(org.springframework.stereotype.Service)") public void within(){} 復制代碼@target()
/*** @target 匹配類級別* 非 Spring環境下,要求的 annotation 的 RetentionPolicy 級別為 RUNTIME* 如下,匹配 標注有 @Service注解 的類 的所有方法*/ @Pointcut("@target(org.springframework.stereotype.Service)") public void target(){} 復制代碼@args()
/*** @args 匹配參數級別* 如下,匹配 某方法的參數 所屬的類 標注有 authority注解 的方法* 即,被攔截的方法的參數中,有的參數所屬的類 標注有 authority注解*/ @Pointcut("@args(com.test.authority)") public void args(){} 復制代碼匹配對象
this()
// ps:這個還沒弄清楚,就不誤人子弟了 @Pointcut("this(com.test.DemoDao)") public void thisDemo() {} 復制代碼target()
// ps:這個還沒弄清楚,就不誤人子弟了 @Pointcut("target(com.test.IDao)") public void targetDemo() {} 復制代碼bean()
// 匹配 Spring bean 容器中,所有名稱以 Service 結尾的 bean @Pointcut("bean(*Service)") public void beanDemo() {} 復制代碼匹配參數
execution()
//匹配任何名稱以 find 開頭而且只有一個 Long 參數的方法 @Pointcut("execution(* *..find*(Long))") public void execution1() { }//匹配任何名稱以 find 開頭的而且第一個參數為 Long 類型的方法 @Pointcut("execution(* *..find*(Long,..))") public void execution2() { } 復制代碼args()
//匹配任何 只有一個Long參數 的方法 @Pointcut("args(Long)") public void args1() { }//匹配第一個參數為 Long 類型的方法 @Pointcut("args(Long,..)") public void args2() { } 復制代碼execution()表達式
結構
execution(<修飾符>? <返回值類型> <方法>(<參數列表>) <異常>?)
- 帶?的,是可選項目,其他的為必選項
實例
/*** execution(<修飾符>? <返回值類型> <方法>(<參數列表>) <異常>?)* 如下,* 匹配 修飾符為 public,* 返回值類型為任意類型,* 方法為 com.test.service包中 以Service結尾的類的所以方法,* 參數列表為任意參數,* 異常為java.lang.IllegalAccessException* 注意,如果指定了異常,那么只會匹配 throws 了 指定異常的方法!!!*/ @Pointcut("execution(public * com.test.service.*Service.*(..) throws java.lang.IllegalAccessException)") public void execution() { } 復制代碼切面的注解
@Pointcut()
作用: 定義一個切入點
@Pointcut()注解的value參數: 一個切面表達
實例
/*** @Pointcut 注解,用于定義一個織入點** 如下,* 匹配 修飾符為 public,* 返回值類型為任意類型,* 方法為 com.test.service包中 以Service結尾的類的所以方法,* 參數列表為任意參數,* 異常為java.lang.IllegalAccessException** 的方法為織入點*/ @Pointcut("execution(public * com.test.service.*Service.*(..) throws java.lang.IllegalAccessException)") public void log() {} 復制代碼@Before()
作用: 被打上 @Before 注解的方法,會在目標方法執行之前執行
@Before()注解的value參數: 除了是一個切面表達式之外,還可以是一個定義好的織入點
實例
/*** @Before 注解的參數 可以是一個切面表達式,也可以是一個織入點* 如下,是一個名為log()的織入點* 此@Before注解 將匹配log()織入點匹配到的方法*/ @Before("log()") public void before(){System.out.println("此語句輸出在目標方法執行之前"); } 復制代碼@After()
作用: 被打上 @After 注解的方法,會在目標方法執行之后執行,不管目標方法是否成功執行或拋出異常
@After()注解的value參數: 除了是一個切面表達式之外,還可以是一個定義好的織入點
實例
/*** @After 注解的參數 可以是一個切面表達式,也可以是一個織入點* 如下,此@After 將匹配log()織入點 或 切面表達式匹配到的方法*/ @After("log() || @annotation(com.demo.security.ToExcel)") public void After(){System.out.println("此語句輸出在目標方法執行之后"); } 復制代碼@Around()
作用: 被打上 @After 注解的方法,會將目標方法“包圍”起來, 在目標方法執行前后做一些操作
@Around()注解的value參數: 除了是一個切面表達式之外,還可以是一個定義好的織入點
實例
/*** 打上 @After 注解的方法,會將目標方法“包圍”起來,在目標方法執行前后做一些操作* 如下,將匹配log()織入點中方法參數名為 token 的方法* 并將此token參數 和 ProceedingJoinPoint對象 作為入參*/ @Around(value = "log() && args(token)") public Object Around(ProceedingJoinPoint joinPoint, String token) throws Throwable {System.out.println("攔截方法的token參數值為:" + token);System.out.println("此語句輸出在目標方法執行之前");try {// 執行目標方法,并返回目標方法的執行結果Object result = joinPoint.proceed(joinPoint.getArgs());return result;} catch (Throwable throwable) {System.out.println("出現異常");// 如果目標方法出現異常,不要`生吞`異常,最好原樣拋出throw throwable;} finally {// @After注解 相當于 finally的語句,不管目標方法是否成功執行或拋出異常,都會執行System.out.println("此語句輸出在目標方法執行之后");} } 復制代碼@AfterReturning()
作用: 此注解與@After注解作用一樣,不同之出在于它多了一個 returning參數,可以用來獲取目標方法返回值,并作為入參帶入方法中
@AfterReturning()注解的value參數: 除了是一個切面表達式之外,還可以是一個定義好的織入點
實例
/*** 使用 returning 獲取目標方法返回值,并取名為result,再將result作為參數帶入方法中*/ @AfterReturning(value = "log() || @annotation(com.demo.security.ToExcel)", returning = "result") public void AfterReturning(Object result) {//?打印目標方法返回結果System.out.println(result);System.out.println("此語句輸出在目標方法執行之后"); } 復制代碼@AfterThrowing()
作用: 此注解不同于@After注解,它只有在目標方法拋出異常之后才會執行
@AfterThrowing()注解的value參數: 除了是一個切面表達式之外,還可以是一個定義好的織入點
實例
/***使用 throwing 獲取目標方法拋出的異常,并取名為e,再將 e 作為參數帶入方法中*/ @AfterThrowing(value="log()", throwing="e") public void AfterThrowing(Exception e){//處理異常e.getMessage();System.out.println("此方法在 目標方法拋出異常時 才執行"); } 復制代碼自定義切面類
首先創建一個java類,然后打上 @Aspect 和 @Component 注解,一個切面就定義好了。
實例
package com.example.demo;import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.*; import org.springframework.stereotype.Component;/** * 自定義切面需要在類上面打上兩個注解 * * @Aspect注解 用于標識這個類是一個自定義切面 * @Component注解 用于將此類交給 Spring 管理 */ @Aspect @Component public class Test {/*** @Pointcut 注解,用于定義一個織入點* <p>* 如下,* 匹配 修飾符為 public,* 返回值類型為任意類型,* 方法為 com.test.service包中 以Service結尾的類的所以方法,* 參數列表為任意參數,* 異常為java.lang.IllegalAccessException* <p>* 的方法為織入點*/@Pointcut("execution(public * com.test.service.*Service.*(..) throws java.lang.IllegalAccessException)")public void log() {}/*** 打上 @Before 注解的方法,會在目標方法執行之前執行** @Before 注解的參數 可以是一個切面表達式,也可以是一個織入點* 如下,是一個名為log()的織入點* 此@Before注解 將匹配log()織入點匹配到的方法*/@Before("log()")public void before() {System.out.println("此語句輸出在目標方法執行之前");}/*** 被打上 @After 注解的方法,會在目標方法執行之后執行,不管目標方法是否成功執行或拋出異常** @After 注解的參數 可以是一個切面表達式,也可以是一個織入點* 如下,此@After 將匹配log()織入點 或 切面表達式匹配到的方法*/@After("log() || @annotation(com.demo.security.ToExcel)")public void After() {System.out.println("此語句輸出在目標方法執行之后");}/*** 打上 @After 注解的方法,會將目標方法“包圍”起來,在目標方法執行前后做一些操作* 如下,將匹配log()織入點中方法參數名為 token 的方法* 并將此token參數 和 ProceedingJoinPoint對象 作為入參*/@Around(value = "log() && args(token)")public Object Around(ProceedingJoinPoint joinPoint, String token) throws Throwable {System.out.println("攔截方法的token參數值為:" + token);System.out.println("@After此語句輸出在目標方法執行之前");try {// 執行目標方法,并返回目標方法的執行結果Object result = joinPoint.proceed(joinPoint.getArgs());return result;} catch (Throwable throwable) {System.out.println("出現異常");// 如果目標方法出現異常,不要`生吞`異常,最好原樣拋出throw throwable;} finally {// @After注解 相當于 finally的語句,不管目標方法是否成功執行或拋出異常,都會執行System.out.println("此語句輸出在目標方法執行之后");}}/*** 使用 returning 獲取目標方法返回值,并取名為result,再將result作為參數帶入方法中*/@AfterReturning(value = "log() || @annotation(com.demo.security.ToExcel)", returning = "result")public void AfterReturning(Object result) {//?打印目標方法返回結果System.out.println(result);System.out.println("此語句輸出在目標方法執行之后");}/*** 使用 throwing 獲取目標方法拋出的異常,并取名為e,再將 e 作為參數帶入方法中*/@AfterThrowing(value = "log()", throwing = "e")public void AfterThrowing(Exception e) {//處理異常e.getMessage();System.out.println("此方法在 目標方法拋出異常時 才執行");} } 復制代碼轉載于:https://juejin.im/post/5cc59f7351882525023565e2
總結
以上是生活随笔為你收集整理的Spring AOP 应用篇的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 绘图和可视化---matplotlib包
- 下一篇: spring-boot使用spring-