SpringAop與AspectJ

AspectJ

AspectJ是一個面向切面的框架,它擴展了Java語言。AspectJ定義了AOP語法,因此它有一個專門的編譯器用來生成遵照Java字節編碼規範的Class文件。java

spring aop

Spring提供了四種類型的Aop支持 
* 基於經典的SpringAOP 
* 純POJO切面 
* @ASpectJ註解驅動的切面 
* 注入式AspectJ切面(其實與Spring並沒有多大的關係,這個就是使用AspectJ這個框架實現Aop編程)spring

基於經典的SpringAop

其使用ProxyFactoryBean建立: 
加強(通知)的類型有: 
前置通知:org.springframework.aop.MethodBeforeAdvice 
後置通知:org.springframework.aop.AfterReturningAdvice 
環繞通知:org.aopalliance.intercept.MethodInterceptor 
異常通知:org.springframework.aop.ThrowsAdviceexpress

public interface IBookDao { public int add() public int delete(); } public class BookDaoImpl implements IBookDao{ public int add() { System.out.println("正在添加圖書..."); return 0; } public int delete() { System.out.println("正在刪除圖書..."); return 0; } } //實現了MethodInterceptor的環繞加強類 public class MyAdvice implements MethodInterceptor{ public Object invoke(MethodInvocation invocation) throws Throwable { System.out.println("Around Advice before method invocation"); Object o = invocation.proceed(); System.out.println("Around Advice after method invocation"); return o; } }

 

//將每個鏈接點都當作切點(攔截每個方法)
<bean id="bookDao" class="com.njust.learning.spring.service.BookDaoImpl"></bean> <bean id="myadvice" class="com.njust.learning.spring.aop.MyAdvice"></bean> <bean id="bookDaoProxy" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="target" ref="bookDao"/> <property name="proxyInterfaces" value="com.njust.learning.spring.service.IBookDao"/> <property name="interceptorNames" value="myadvice"/> </bean>

 

使用RegexMethodPointcutAdvisor針對某些特定的方法進行攔截加強
<bean id="bookDao" class="com.njust.learning.spring.service.BookDaoImpl"></bean> <bean id="myadvice" class="com.njust.learning.spring.aop.MyAdvice"></bean> <bean id="rmpAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"> <!--patterns,若是有多個指定的值的話,能夠使用,隔開,例如value=".*add,.*delete"--> <property name="patterns" value=".*add"/> <property name="advice" ref="myadvice"/> </bean> <!--使用的時候使用這個id,而不是原始的那個id--> <bean id="bookDaoProxy" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="target" ref="bookDao"/> <property name="proxyInterfaces" value="com.njust.learning.spring.service.IBookDao"/> <property name="interceptorNames" value="rmpAdvisor"/> </bean>

 

注意

像上面這樣,每定義一個dao都須要定義一個ProxyFactoryBean,顯得很麻煩,因此咱們引入自動代理,也就是自動建立代理對象編程

BeanNameAutoProxyCreator

<bean id="bookDao" class="com.njust.learning.spring.service.BookDaoImpl"></bean> <bean id="myadvice" class="com.njust.learning.spring.aop.MyAdvice"></bean> <bean id="rmpAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"> <!--patterns,若是有多個指定的值的話,能夠使用,隔開,例如value=".*add,.*delete"--> <property name="patterns" value=".*add"/> <property name="advice" ref="myadvice"/> </bean> <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"> <property name="beanNames" value="*Dao"></property> <property name="interceptorNames" value="rmpAdvisor"></property> </bean>

 

DefaultAdvisorAutoProxyCreator

<bean id="bookDao" class="com.njust.learning.spring.service.BookDaoImpl"></bean> <bean id="myadvice" class="com.njust.learning.spring.aop.MyAdvice"></bean> <bean id="rmpAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"> <!--patterns,若是有多個指定的值的話,能夠使用,隔開,例如value=".*add,.*delete"--> <property name="patterns" value=".*add"/> <property name="advice" ref="myadvice"/> </bean> <!--根據切面中生成信息生成代理--> <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/>

 

純POJO切面,須要使用XML進行配置

public interface IBookDao { public int add(); public int delete(); } public class BookDaoImpl implements IBookDao{ public int add() { int a = 1/0; System.out.println("正在添加圖書..."); return 0; } public int delete() { System.out.println("正在刪除圖書..."); return 0; } }

 

public class PojoAdvice { public void before(){ System.out.println("前置通知"); } public void after(Object returnval){ System.out.println("後置通知"+",處理後的結果爲:"+returnval); } public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { System.out.println("環繞前置加強..."); Object o = proceedingJoinPoint.proceed(); System.out.println("環繞後置加強..."); return o; } public void afterThrowing(Throwable e){ System.out.println("異常通知:"+e.getMessage()); } }

 

<bean id="bookDao" class="com.njust.learning.spring.service.BookDaoImpl"></bean> <bean id="pojoAdvice" class="com.njust.learning.spring.pojoaop.PojoAdvice"></bean> <aop:config> <aop:pointcut id="p" expression="execution (* *.add(..))"/> <aop:aspect ref="pojoAdvice"> <aop:before method="before" pointcut-ref="p"></aop:before> <!--經過設置returning來將返回值傳遞給通知--> <aop:after-returning method="after" pointcut-ref="p" returning="returnval"/> <aop:around method="around" pointcut-ref="p"/> <!--經過設置returning來將異常對象傳遞給通知--> <aop:after-throwing method="afterThrowing" pointcut-ref="p" throwing="e"/> </aop:aspect> </aop:config>

 

聯繫

咱們藉助於Spring Aop的命名空間能夠將純POJO轉換爲切面,實際上這些POJO只是提供了知足切點的條件時所須要調用的方法,可是,這種技術須要XML進行配置,不能支持註解 
因此spring借鑑了AspectJ的切面,以提供註解驅動的AOP,本質上它依然是Spring基於代理的AOP,只是編程模型與AspectJ徹底一致,這種風格的好處就是不須要使用XML進行配置markdown

本文爲學習而轉載 https://blog.csdn.net/qq_21050291/article/details/72523138
相關文章
相關標籤/搜索