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