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

歡迎訪問 生活随笔!

生活随笔

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

javascript

Spring之面向切面编程AOP(三)

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

上兩節提到Spring的裝配bean還有高級裝配,這一節就是Spring的另一個核心內容-AOP

AOP的基本概念

AOP稱為面向切面編程,在程序開發中主要用來解決一些系統層面上的問題,比如日志,事務,權限等通用的輔助模塊,在系統的很多模塊都要添加。

日志,事務,權限等就是切面,使用這種面向切面編程時,我們仍然可以在一個地方聲明通用功能(切面),然后聲明這個功能在何時通過何種方式使用,而無需修改應用這個切面的模塊。這樣做的好處是我們的關注點可以集中在模塊,而不是分散的通用功能,其次,模塊的代碼因此會變得整潔。

AOP的組成

(1)Aspect(切面):通常是一個類,里面可以定義切入點和通知

(2)JointPoint(連接點):程序執行過程中明確的點,一般是方法的調用

(3)Advice(通知):AOP在特定的切入點上執行的增強處理,有before,after,afterReturning,afterThrowing,around

(4)Pointcut(切入點):就是帶有通知的連接點,在程序中主要體現為書寫切入點表達式

(5)AOP代理:AOP框架創建的對象,代理就是目標對象的加強。Spring中的AOP代理可以使JDK動態代理,也可以是CGLIB代理,前者基于接口,后者基于子類

例如:

@Aspect @Component public class Audience { @Pointcut("execution(* com.hsb.beans.Perform.show(..))") public void performance() { } @Before("performance()") public void beforeShow() { System.out.println("message from beforeShow"); }

Audience就是一個切面
@Pointcut("execution(* com.hsb.beans.Perform.show(..))") 是切點
beforeShow()是連接點
@Before(“performance()”) 就是通知

下面是兩種常用的aop方法:

1.在XML中聲明切面

  • a.編寫一個原始類
package com.hsb.beans; import org.springframework.stereotype.Repository; @Repository public class Perform { public void show(){ System.out.println("message from Perform.show()"); } }
  • b.編寫一個切面
package com.hsb.aop; import org.aspectj.lang.ProceedingJoinPoint; public class Audience { public void beforeShow(){ System.out.println("message from beforeShow"); } public void afterShow(){ System.out.println("message from afterShow"); } public void around(ProceedingJoinPoint joinpoint){ System.out.println("message from Start around"); long start = System.currentTimeMillis(); try { joinpoint.proceed(); } catch (Throwable e) { e.printStackTrace(); } long end = System.currentTimeMillis(); System.out.println("message from End around total : "+(end-start)+" ms"); } }

代碼中的joinpoint.proceed(),這句話就是實際調用切點方法,也就是本例中的show()。如果切面類中定義了around通知,通知一定要加上這句話,否則要切點方法不會被調用!
- c.配置XML

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd" default-lazy-init="true"> <context:component-scan base-package="com.hsb.beans" /> <bean id="audience" class="com.hsb.aop.Audience" /> <aop:config> <aop:aspect ref="audience"> <aop:pointcut expression="execution(* com.hsb.beans.Perform.show(..))" id="performance" /> <aop:before method="beforeShow" pointcut-ref="performance" /> <aop:after method="afterShow" pointcut-ref="performance" /> <aop:around method="around" pointcut-ref="performance" /> </aop:aspect> </aop:config> </beans>

首先將audience聲明為一個bean,
<aop:aspect ref="audience">定義切面。
<aop:pointcut>定義切點。
<aop:before>等定義通知。

這樣就實現了在xml中實現aop,原理是,一個代理類封裝了需要切面的這個模塊,并攔截了被通知方法的調用,再把調用方法轉發給真正的bean。
當攔截到方法調用時,先執行切面邏輯,再調用目標方法。

2.注解切面

  • a.編寫一個原始類
package com.hsb.beans; import org.springframework.stereotype.Repository; @Repository public class Perform { public void show(){ System.out.println("message from Perform.show()"); } }
  • b.編寫一個切面
package com.hsb.aop; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.springframework.stereotype.Component; @Aspect @Component public class Audience { @Pointcut("execution(* com.hsb.beans.Perform.show(..))") public void performance() { } @Before("performance()") public void beforeShow() { System.out.println("message from beforeShow"); } @After("performance()") public void afterShow() { System.out.println("message from afterShow"); } @Around("performance()") public void around(ProceedingJoinPoint joinpoint) { System.out.println("message from Start around"); long start = System.currentTimeMillis(); try { joinpoint.proceed(); } catch (Throwable e) { e.printStackTrace(); } long end = System.currentTimeMillis(); System.out.println("message from End around total : " + (end - start) + " ms"); } }

@Aspect將此類聲明為切面類,@Component將此類聲明為bean放到spring容器中,@Pointcut將下面的performance聲明為一個切點,并將Perform中的show()方法進行了關聯。execution(* com.hsb.beans.Perform.show(..))的意思是,執行此方法時,忽略返回值,參數類型和個數忽略。還可以更加簡寫,用于匹配合適的方法,譬如對Perform類的全部方法進行匹配就是com.hsb.beans.Perform.*。

  • c.配置xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd" default-lazy-init="true"> <context:component-scan base-package="com.hsb.*" /> <aop:aspectj-autoproxy proxy-target-class="true"/> </beans>

可以看見此處就沒有使用<aop:config />聲明,而是使用<aop:aspectj-autoproxy proxy-target-class="true" />這句話的意思是自動在spring上下文中創建一個AnnotationAwareAspectJAutoProxyCreator類,它會自動代理一些bean,這些bean的方法需要與使用@Aspect注解的bean中所定義的切點相匹配,而這些切點又是使用@Pointcut注解定義出來的。proxy-target-class=”true”的意思是使用基于類的代理使用cglib庫,如果為false則使用jdk自帶的基于接口的代理

如上所示,完全是一樣的效果??梢钥闯鍪褂米⒔鉁p少了很多工作,不容易出錯,各個組件間的耦合度降低了。試想,如果一個大型項目中有很多切面,切點,如果全部去xml中配置,將會是一項極為艱苦的工作,但是如果使用注解就可以做很少的工作完成這一切。

總結

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

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