日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

一个简单的例子,学习自定义注解和AOP

發(fā)布時(shí)間:2023/12/3 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 一个简单的例子,学习自定义注解和AOP 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

轉(zhuǎn)載自? ?一個(gè)簡(jiǎn)單的例子,學(xué)習(xí)自定義注解和AOP

記得今年年初剛開(kāi)始面試的時(shí)候,被問(wèn)的最多的就是你知道Spring的兩大核心嘛?那你說(shuō)說(shuō)什么是AOP,什么是IOC?我相信你可能也被問(wèn)了很多次了。

?

1、到底是什么是AOP?

所謂AOP也就是面向切面編程,能夠讓我們?cè)诓挥绊懺袠I(yè)務(wù)功能的前提下,橫切擴(kuò)展新的功能。這里面有一個(gè)比較顯眼的詞我們需要注意一下,橫切,它是基于橫切面對(duì)程序進(jìn)行擴(kuò)展的。

?

2、AOP相關(guān)術(shù)語(yǔ)

在Spring的AOP中有很多的術(shù)語(yǔ),而且容易混淆,大家一定要先搞清楚這幾個(gè)概念:

  • 連接點(diǎn)(Joinpoint):在程序執(zhí)行過(guò)程中某個(gè)特定的點(diǎn),比如類初始化前、類初始化后,方法調(diào)用前,方法調(diào)用后;

  • 切點(diǎn)(Pointcut:所謂切點(diǎn)就是你所切取的類中的方法,比如你橫切的這個(gè)類中有兩個(gè)方法,那么這兩個(gè)方法都是連接點(diǎn),對(duì)這兩個(gè)方法的定位就稱之為切點(diǎn);

  • 增強(qiáng)(Advice:增強(qiáng)是織入到連接點(diǎn)上的一段程序,另外它還擁有連接點(diǎn)的相關(guān)信息;

  • 目標(biāo)對(duì)象(Target):增強(qiáng)邏輯的織入目標(biāo)類,就是我的增強(qiáng)邏輯植入到什么位置;

  • 引介(Introduction:一種特殊的增強(qiáng),它可以為類添加一些屬性喝方法;

  • 織入(Weaving:織入就是講增強(qiáng)邏輯添加到目標(biāo)對(duì)象的過(guò)程;

  • 代理(Proxy:一個(gè)類被AOP織入增強(qiáng)后,就會(huì)產(chǎn)生一個(gè)結(jié)果類,他是融合了原類和增強(qiáng)邏輯的代理類;

  • 切面(Aspect:切面由切點(diǎn)和增強(qiáng)組成,他是橫切邏輯定義和連接點(diǎn)定義的組成;

?

3、AOP功能實(shí)踐

我們這里主要是學(xué)習(xí)SpringBoot中的一些功能,所以我們這里用的是SpringBoot工程,版本也是最新的2.0.5版本。

創(chuàng)建SpringBoot工程就不說(shuō)了,我們直接引入Maven的依賴:

<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.0.5.RELEASE</version><relativePath/>?<!-- lookup parent from repository --></parent><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><exclusions><exclusion><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-tomcat</artifactId></exclusion></exclusions></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jetty</artifactId></dependency><!-- 引入AOP --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.6.1</version><configuration><source>1.8</source><target>1.8</target></configuration></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-surefire-plugin</artifactId><version>2.20</version><configuration><skip>true</skip></configuration></plugin><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><executions></executions></plugin></plugins></build>

首先我們來(lái)創(chuàng)建一個(gè)Controller類:

@RestController public?class?LoginController {@GetMapping(value =?"/username")public?String?getLoginUserName(String?userName, Integer age) {return?userName +?" --- "?+ age;} }

創(chuàng)建切面:

@Aspect @Component public?class?LogAspect?{/*** 功能描述: 攔截對(duì)這個(gè)包下所有方法的訪問(wèn)** @param:[]* @return:void**/@Pointcut("execution(* com.example.springbootaop.controller.*.*(..))")public?void?loginLog()?{}// 前置通知@Before("loginLog()")public?void?loginBefore(JoinPoint joinPoint)?{// 我們從請(qǐng)求的上下文中獲取request,記錄請(qǐng)求的內(nèi)容ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();HttpServletRequest request = attributes.getRequest();System.out.println("請(qǐng)求路徑 : "?+ request.getRequestURL());System.out.println("請(qǐng)求方式 : "?+ request.getMethod());System.out.println("方法名 : "?+ joinPoint.getSignature().getName());System.out.println("類路徑 : "?+ joinPoint.getSignature().getDeclaringTypeName());System.out.println("參數(shù) : "?+ Arrays.toString(joinPoint.getArgs()));}@AfterReturning(returning =?"object", pointcut =?"loginLog()")public?void?doAfterReturning(Object?object)?{System.out.println("方法的返回值 : "?+?object);}// 方法發(fā)生異常時(shí)執(zhí)行該方法@AfterThrowing(throwing =?"e",pointcut =?"loginLog()")public?void?throwsExecute(JoinPoint joinPoint, Exception e)?{System.err.println("方法執(zhí)行異常 : "?+ e.getMessage());}// 后置通知@After("loginLog()")public?void?afterInform()?{System.out.println("后置通知結(jié)束");}// 環(huán)繞通知@Around("loginLog()")public?Object?surroundInform(ProceedingJoinPoint proceedingJoinPoint)?{System.out.println("環(huán)繞通知開(kāi)始...");try?{Object o = ?proceedingJoinPoint.proceed();System.out.println("方法環(huán)繞proceed,結(jié)果是 :"?+ o);return?o;}?catch?(Throwable e) {e.printStackTrace();return?null;}} }

注解概述:

  • @Apsect:將當(dāng)前類標(biāo)識(shí)為一個(gè)切面;

  • @Pointcut:定義切點(diǎn),這里使用的是條件表達(dá)式;

  • @Before:前置增強(qiáng),就是在目標(biāo)方法執(zhí)行之前執(zhí)行;

  • @AfterReturning:后置增強(qiáng),方法退出時(shí)執(zhí)行;

  • @AfterThrowing:有異常時(shí)該方法執(zhí)行;

  • @After:最終增強(qiáng),無(wú)論什么情況都會(huì)執(zhí)行;

  • @Afround:環(huán)繞增強(qiáng);

?

測(cè)試:

異常測(cè)試:

?

4、定義自定義注解

應(yīng)用場(chǎng)景:在我之前上個(gè)項(xiàng)目的時(shí)候,有這樣一個(gè)注解,就是在訪問(wèn)其他接口的時(shí)候必須要登錄,那么這個(gè)時(shí)候我們就定義一個(gè)注解,讓它去對(duì)用戶是否登錄進(jìn)行校驗(yàn),那么基于這樣的一個(gè)場(chǎng)景,我們來(lái)定義一個(gè)校驗(yàn)登錄的注解。

創(chuàng)建一個(gè)注解:

@Target({ElementType.METHOD,?ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) public @interface Auth {String?desc()?default?"驗(yàn)證是否登錄"; }

創(chuàng)建一個(gè)AOP切面:

@Aspect @Component public?class?LoginAspect?{@Pointcut(value =?"@annotation(com.example.springbootaop.annotation.Auth)")public?void?access()?{}@Before("access()")public?void?before()?{System.out.println("開(kāi)始驗(yàn)證用戶是否登錄...");}@Around("@annotation(auth)")public?Object?around(ProceedingJoinPoint pj, Auth auth)?{// 獲取注解中的值System.out.println("注解中的值 : "?+ auth.desc());try?{// 檢驗(yàn)是否登錄 true 已經(jīng)登錄 ?false 未登錄Boolean flag =?false;if?(flag ==?true) {return?"登錄成功";}?else?{return?"未登錄";}}?catch?(Throwable throwable) {return?null;}} }

測(cè)試未登錄:

測(cè)試登錄:

這樣我們就可以簡(jiǎn)單的實(shí)現(xiàn)了一個(gè)登錄校驗(yàn)的注解。

通過(guò)今天的分享你會(huì)使用AOP和自定義注解了嗎?我把源碼的地址放在下面,有興趣的朋友可以看看。

https://github.com/liangbintao/SpringBootIntegration.git

總結(jié)

以上是生活随笔為你收集整理的一个简单的例子,学习自定义注解和AOP的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。