SpringBoot之@Aspect注解解讀
@Aspect注解
AOP:面向切面編程,通過預(yù)編譯方式和運行期動態(tài)代理實現(xiàn)程序功能的統(tǒng)一維護的一種技術(shù)。而@Aspect 就是把一個類定義為切面供容器讀取。
- @before: 前置通知,在方法執(zhí)行之前執(zhí)行。
- @After:后置通知,在方法執(zhí)行后執(zhí)行。
- @AfterReturning: 返回通知,在方法返回結(jié)果之后執(zhí)行。
- @AfterThrowing:異常通知,在方法拋出異常之后執(zhí)行。
- @Around:環(huán)繞通知,圍繞著方法執(zhí)行。
1. 實現(xiàn)步驟
1.1 導(dǎo)入jar包
這兩個選一個就可以了,推薦使用第一個,因為第一個項目中肯定會用到的。
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>2.5.4</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency>
1.2 創(chuàng)建一個實體類
@Component @Aspect public class TestAspect { @Pointcut("execution( * com.atguigu.gulimall.product.controller.CouponController.*(..))") private void log(){ } @Before("log()") public void TestBefore(){ System.out.println("在調(diào)用方法的時候都會調(diào)用這個切面"); }
把這個類加入到容器中,然后再添加上注解就可以就可以看成是一個切面容器。 ?
2. 語法
execution( * com.atguigu.gulimall.product.controller.CouponController.*(..)); // 第一個* 代表任意修飾符及任意返回值下的CouponController類下的所有方法。 // 第二個* 代表CouponController類下的所有方法。 // (..) 代表任意參數(shù)
// 匹配CouponController類下面的所有共有方法。 @Pointcut("execution( public * com.atguigu.gulimall.product.controller.CouponController.*(..))") // 第一個* 代表任意返回值 // 第二個* 當(dāng)表任意方法 //(..) 代表任意參數(shù)
// 返回double 類型數(shù)值的方法 @Pointcut("execution( public Double com.atguigu.gulimall.product.controller.CouponController.*(..))")
// 匹配第一個參數(shù)為Double的方法。 @Pointcut("execution( public Double com.atguigu.gulimall.product.controller.CouponController.*(Double,..))")
// 匹配兩個參數(shù)都為double 的方法。 @Pointcut("execution( public Double com.atguigu.gulimall.product.controller.CouponController.*(Double,Double))")
3. 簡單實現(xiàn)
3.1 @Before
在方法執(zhí)行前執(zhí)行該方法,并且可以通過(JoinPoint類)獲取請求參數(shù)和方法。
@Component @Aspect public class TestAspect { @Pointcut("execution( * com.atguigu.gulimall.product.controller.CouponController.*(..))") private void log(){ } @Before("log()") public void TestBefore(JoinPoint joinPoint){ Object[] args = joinPoint.getArgs(); String name = joinPoint.getSignature().getName(); System.out.println(Arrays.asList(args).toString() +" "+ name); } }
@RestController @RequestMapping("product/coupon") public class CouponController { /** * 列表 */ @RequestMapping("/list") public R list(@RequestBody Map<String, Object> params){ return R.ok().put("page", "測試專用"); } }
3.2 @After
后置通知,在方法執(zhí)行后執(zhí)行??梢酝ㄟ^(JoinPoint類)獲取請求參數(shù)和方法。
當(dāng)方法拋出異常的時候也不會影響執(zhí)行切點方法,也就是說不管如何都是會執(zhí)行切面方法的。
@Component @Aspect public class TestAspect { @Pointcut("execution( * com.atguigu.gulimall.product.controller.CouponController.*(..))") private void log(){ } @After("log()") public void TestBefore(JoinPoint joinPoint){ Object[] args = joinPoint.getArgs(); String name = joinPoint.getSignature().getName(); System.out.println(Arrays.asList(args).toString() +" "+ name); } }
3.3 @AfterReturning
當(dāng)方法正常執(zhí)行返回后才執(zhí)行次方法,如果拋出異常就不會執(zhí)行此方法。
/** * 列表 */ @RequestMapping("/list") public R list(@RequestBody Map<String, Object> params){ PageUtils<CouponEntity> page = couponService.queryPage(params); List<CouponEntity> list = page.getList(); String s = JSONObject.toJSONString(list); // 當(dāng)這行拋出異常的時候就不會再執(zhí)行切點方法了。 int i = 1/0; return R.ok().put("page", s); }
@Component @Aspect public class TestAspect { @Pointcut("execution( * com.atguigu.gulimall.product.controller.CouponController.*(..))") private void log(){ } @AfterReturning("log()") public void TestBefore(JoinPoint joinPoint){ Object[] args = joinPoint.getArgs(); String name = joinPoint.getSignature().getName(); System.out.println(Arrays.asList(args).toString() +" "+ name); } }
3.4 @AfterThrowing(“log()”)
只有在拋出異常的時候才會調(diào)用切點方法。如果不拋出異常就不會調(diào)用切點方法。
@RequestMapping("/list") public R list(@RequestBody Map<String, Object> params){ PageUtils<CouponEntity> page = couponService.queryPage(params); List<CouponEntity> list = page.getList(); String s = JSONObject.toJSONString(list); int i = 1/0; return R.ok().put("page", s); }
@Component @Aspect public class TestAspect { @Pointcut("execution( * com.atguigu.gulimall.product.controller.CouponController.*(..))") private void log(){ } @AfterThrowing("log()") public void TestBefore(JoinPoint joinPoint){ Object[] args = joinPoint.getArgs(); String name = joinPoint.getSignature().getName(); System.out.println(Arrays.asList(args).toString() +" "+ name); } }
3.5 @Around
- 使用 ProceedingJoinPoint 獲取參數(shù)信息
- 使用joinPoint.proceed()方法調(diào)用方法。
- 只有調(diào)用上面的方法才能夠執(zhí)行方法
@Component @Aspect public class TestAspect { @Pointcut("execution( * com.atguigu.gulimall.product.controller.CouponController.*(..))") private void log(){ } @Around("log()") public R TestBefore(ProceedingJoinPoint joinPoint) throws Throwable { Object[] args = joinPoint.getArgs(); Object o = args[0]; HashMap<String, String> stringStringHashMap = null; if (o instanceof Map){ stringStringHashMap = (HashMap<String, String>) o; } if(stringStringHashMap.get("name").equals("xiaobai")){ // 當(dāng)滿足參數(shù)中name值xiaobai的時候,才會調(diào)用下面的方法。 R proceed = (R) joinPoint.proceed(); return proceed; }else { return R.ok().put("name","小周"); } } }
/** * 列表 */ @RequestMapping("/list") public R list(@RequestBody Map<String, Object> params){ PageUtils<CouponEntity> page = couponService.queryPage(params); List<CouponEntity> list = page.getList(); String s = JSONObject.toJSONString(list); return R.ok().put("page", s); }
4. 結(jié)合自定義注解實現(xiàn)
package com.atguigu.gulimall.product.annoation; import java.lang.annotation.*; /** * @author liruiqing * 注解和@Aspect注解之間的聯(lián)合使用 */ @Documented @Target({ElementType.METHOD}) // 在方法上加 @Retention(RetentionPolicy.RUNTIME) // 運行時 public @interface AnnotationTest { }
@RequestMapping("/list") @AnnotationTest public R list(@RequestBody Map<String, Object> params){ PageUtils<CouponEntity> page = couponService.queryPage(params); List<CouponEntity> list = page.getList(); String s = JSONObject.toJSONString(list); return R.ok().put("page", s); }
@Pointcut("@annotation(com.atguigu.gulimall.product.annoation.AnnotationTest)") private void annotation(){ } @After("annotation()") public void testAnnotation(){ System.out.println("執(zhí)行注解注釋的方法后執(zhí)行此方法"); }
這樣就可以實現(xiàn)切面了。
到此這篇關(guān)于SpringBoot之@Aspect注解解讀的文章就介紹到這了,更多相關(guān)@Aspect注解內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
解決IDEA Maven下載依賴時報錯ERROR - #org.jetbrains.ide
這篇文章主要介紹了解決IDEA Maven下載依賴時報錯ERROR - #org.jetbrains.idea.maven - Cannot reconnect.問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-08-08springBoot整合CXF并實現(xiàn)用戶名密碼校驗的方法
這篇文章主要介紹了springBoot整合CXF并實現(xiàn)用戶名密碼校驗的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-08-08SpringBoot項目打包war包時無法運行問題的解決方式
在開發(fā)工程中,使用啟動類啟動能夠正常啟動并測試,下面這篇文章主要給大家介紹了關(guān)于SpringBoot項目打包war包時無法運行問題的解決方式,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下2022-06-06java?stream?distinct()如何按一個或多個指定對象字段進行去重
這篇文章主要介紹了java?stream?distinct()如何按一個或多個指定對象字段進行去重問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-12-12