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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

Spring学习之AOP(面向切面编程)

發布時間:2024/4/13 javascript 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring学习之AOP(面向切面编程) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

動態代理

??? 代理模式是常用的java設計模式,他的特征是代理類與委托類有同樣的接口,代理類主要負責為委托類預處理消息、過濾消息、把消息轉發給委托類,以及事后處理消息等。代理類與委托類之間通常會存在關聯關系,一個代理類的對象與一個委托類的對象關聯,代理類的對象本身并不真正實現服務,而是通過調用委托類的對象的相關方法,來提供特定的服務

????動態代理好比如影星和經紀人,實際演戲的是影星,經紀人為影星處理好拍戲前后的事情.實際演戲的是影星.影公司找影星拍戲前需要先找到經紀人,但最終拍戲還是得找影星執行這個動作.?

?public?interface?Dinner?{//吃晚飯的方法public?void?haveDinner(); } //委托類 public?class?MyDinner?implements?Dinner{@Overridepublic?void?haveDinner()?{System.out.println("媽媽做的晚飯真好吃....");} } import?java.lang.reflect.InvocationHandler; import?java.lang.reflect.Method; import?java.lang.reflect.Proxy; //代理類 public?class?MyDinnerProxy?implements?InvocationHandler?{private?Object?originalObject;?//被代理的原始對象//綁定被代理對象,返回一個代理對象public?Object?getProxy(Object?obj){this.originalObject?=?obj;//返回一個代理對象return?Proxy.newProxyInstance(obj.getClass().getClassLoader(),?obj.getClass().getInterfaces(),?this);}?@Overridepublic?Object?invoke(Object?proxy,?Method?method,?Object[]?args)throws?Throwable?{Object?result?=?null;System.out.println("吃飯之前洗手保持個人衛生...");result?=?method.invoke(this.originalObject,?args);System.out.println("吃飯之后洗碗保持廚房衛生....");return?result;}? } //測試類 public?class?MyDinnerProxyDemo?{public?static?void?main(String[]?args)?{Dinner?din?=?new?MyDinner();//不是使用代理對象的效果//din.haveDinner();MyDinnerProxy?proxy?=?new?MyDinnerProxy();//返回了一個代理對象din?=?(Dinner)proxy.getProxy(din);//執行代理對象的方法din.haveDinner();} }

AOP簡介?

AOP(Aspect-Oriented Programming, 面向切面編程): 是一種新的方法論, 是對傳統 OOP(Object-Oriented Programming, 面向對象編程) 的補充.

AOP 的主要編程對象是切面(aspect), 而切面模塊化橫切關注點.

在應用 AOP 編程時, 仍然需要定義公共功能, 但可以明確的定義這個功能在哪里, 以什么方式應用, 并且不必修改受影響的類. 這樣一來橫切關注點就被模塊化到特殊的對象(切面)里.

AOP 的好處:

–每個事物邏輯位于一個位置, 代碼不分散, 便于維護和升級

–業務模塊更簡潔, 只包含核心業務代碼.

?

?

切面(Aspect):? 橫切關注點(跨越應用程序多個模塊的功能)被模塊化的特殊對象

通知(Advice):? 切面必須要完成的工作

目標(Target): 被通知的對象

代理(Proxy): 向目標對象應用通知之后創建的對象

連接點(Joinpoint):程序執行的某個特定位置:如類某個方法調用前、調用后、方法拋出異常后等。連接點由兩個信息確定:方法表示的程序執行點;相對點表示的方位。例如 ArithmethicCalculator#add() 方法執行前的連接點,執行點為 ArithmethicCalculator#add(); 方位為該方法執行前的位置

切點(pointcut):每個類都擁有多個連接點:例如 ArithmethicCalculator的所有方法實際上都是連接點,即連接點是程序類中客觀存在的事務。AOP 通過切點定位到特定的連接點。類比:連接點相當于數據庫中的記錄,切點相當于查詢條件。切點和連接點不是一對一的關系,一個切點匹配多個連接點,切點通過 org.springframework.aop.Pointcut接口進行描述,它使用類和方法作為連接點的查詢條件。???

切面就是一個帶有 @Aspect 注解的 Java 類.

切面需要在IOC容器中,@Component

通知是標注有某種注解的簡單的 Java 方法.

AspectJ支持 5 種類型的通知注解:

–@Before: 前置通知, 在方法執行之前執行

–@After: 后置通知, 在方法執行之后執行

–@AfterRunning: 返回通知, 在方法返回結果之后執行

–@AfterThrowing: 異常通知, 在方法拋出異常之后

–@Around: 環繞通知, 圍繞著方法執行

?可以用@Order(1)指定不同切面的優先級(也就是執行順序),數字越小優先級越高

?在 AspectJ切面中, 可以通過 @Pointcut注解將一個切入點聲明成簡單的方法. 切入點的方法體通常是空的, 因為將切入點定義與應用程序邏輯混在一起是不合理的

import?org.aspectj.lang.annotation.After; import?org.aspectj.lang.annotation.Aspect; import?org.aspectj.lang.annotation.Before; import?org.springframework.stereotype.Component; /***?AOP?的?helloWorld*?1.?加入?jar?包*?com.springsource.net.sf.cglib-2.2.0.jar*?com.springsource.org.aopalliance-1.0.0.jar*?com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar*?spring-aspects-4.0.0.RELEASE.jar*?*?2.?在?Spring?的配置文件中加入?aop?的命名空間。?*?*?3.?基于注解的方式來使用?AOP*?3.1?在配置文件中配置自動掃描的包:?<context:component-scan?base-package="com.atguigu.spring.aop"></context:component-scan>*?3.2?加入使?AspjectJ?注解起作用的配置:?<aop:aspectj-autoproxy></aop:aspectj-autoproxy>?使@Before和@After起作用*?為匹配的類自動生成動態代理對象.?*?*?4.?編寫切面類:?*?4.1?一個一般的?Java?類*?4.2?在其中添加要額外實現的功能.?**?5.?配置切面*?5.1?切面必須是?IOC?中的?bean:?添加?@Component?注解*?5.2?聲明是一個切面:?添加?@Aspect*?5.3?配置切面優先級@Order(1)*?5.3.1?給方法配置通知注解. 前置通知:?@Before("execution(public?int?com.atguigu.spring.aop.ArithmeticCalculator.*(int,?int))")*?6.?在通知中訪問連接細節:?可以在通知方法中添加?JoinPoint?類型的參數,?從中可以訪問到目標方法的簽名和方法的參數.?*?*/ //通過添加?@Aspect?注解聲明一個?bean?是一個切面! @Order(2) @Aspect @Component public?class?LoggingAspect?{ /***?定義一個方法,?用于聲明切入點表達式.?一般地,?該方法中再不需要添入其他的代碼.?*?使用?@Pointcut?來聲明切入點表達式.?*?后面的其他通知直接使用方法名來引用當前的切入點表達式.?*/@Pointcut("execution(public?int?com.atguigu.spring.aop.ArithmeticCalculator.*(..))")public?void?declareJointPointExpression(){}//聲明是一個前置通知,在目標方法之前執行@Before("declareJointPointExpression()")public?void?beforeMethod(JoinPoint?joinPoint){String?methodName?=?joinPoint.getSignature().getName();Object?[]?args?=?joinPoint.getArgs();System.out.println("The?method?"?+?methodName?+?"?begins?with?"?+?Arrays.asList(args));} //聲明是一個后置通知,在目標方法執行后(發生異常后)執行,還不能訪問目標方法的執行結果@After("execution(*?com.atguigu.spring.aop.*.*(..))")public?void?afterMethod(JoinPoint?joinPoint){String?methodName?=?joinPoint.getSignature().getName();System.out.println("The?method?"?+?methodName?+?"?ends");}/***?在方法法正常結束受執行的代碼*?返回通知是可以訪問到方法的返回值的!*/@AfterReturning(value="declareJointPointExpression()",returning="result")public?void?afterReturning(JoinPoint?joinPoint,?Object?result){String?methodName?=?joinPoint.getSignature().getName();System.out.println("The?method?"?+?methodName?+?"?ends?with?"?+?result);}/***?在目標方法出現異常時會執行的代碼.*?可以訪問到異常對象;?且可以指定在出現特定異常時在執行通知代碼*/@AfterThrowing(value="declareJointPointExpression()",throwing="e")public?void?afterThrowing(JoinPoint?joinPoint,?Exception?e){String?methodName?=?joinPoint.getSignature().getName();System.out.println("The?method?"?+?methodName?+?"?occurs?excetion:"?+?e);}/***?環繞通知需要攜帶?ProceedingJoinPoint?類型的參數.?*?環繞通知類似于動態代理的全過程:?ProceedingJoinPoint?類型的參數可以決定是否執行目標方法.*?且環繞通知必須有返回值,?返回值即為目標方法的返回值*//*@Around("execution(public?int?com.atguigu.spring.aop.ArithmeticCalculator.*(..))")public?Object?aroundMethod(ProceedingJoinPoint?pjd){Object?result?=?null;String?methodName?=?pjd.getSignature().getName();try?{//前置通知System.out.println("The?method?"?+?methodName?+?"?begins?with?"?+?Arrays.asList(pjd.getArgs()));//執行目標方法result?=?pjd.proceed();//返回通知System.out.println("The?method?"?+?methodName?+?"?ends?with?"?+?result);}?catch?(Throwable?e)?{//異常通知System.out.println("The?method?"?+?methodName?+?"?occurs?exception:"?+?e);throw?new?RuntimeException(e);}//后置通知System.out.println("The?method?"?+?methodName?+?"?ends");return?result;} } //另一個切面 package?com.atguigu.spring.aop; import?java.util.Arrays; import?org.aspectj.lang.JoinPoint; import?org.aspectj.lang.annotation.Aspect; import?org.aspectj.lang.annotation.Before; import?org.springframework.core.annotation.Order; import?org.springframework.stereotype.Component; @Order(1) @Aspect @Component public?class?VlidationAspect?{ //重用另一個包的一個類里的切入點表達式@Before("com.atguigu.spring.aop.LoggingAspect.declareJointPointExpression()")public?void?validateArgs(JoinPoint?joinPoint){System.out.println("-->validate:"?+?Arrays.asList(joinPoint.getArgs()));}}

?

轉載于:https://blog.51cto.com/s5650326/1717136

總結

以上是生活随笔為你收集整理的Spring学习之AOP(面向切面编程)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。