最近在系統中須要實現用戶某些操做添加積分, 但願實現對系統現有的代碼進行最小嵌入,所以使用Spring AOP的切面編程將很好實現該需求,達到最小耦合度。在Spring AOP中的通知都是針對方法層級進行通知,相對與Struct中針對類層級通知,具備更好的靈活性。
html
/*方法攔截*/ MethodInterceptor /*返回攔截*/ AfterReturningAdvice /*事件攔截*/ HandlerInterceptor MethodInvocation
一、經典的基於代理的AOP(各版本Spring)
java
二、@AspectJ註解驅動的切面(僅Spring 2.0);
正則表達式
三、純POJO切面(僅Spring2.0);
spring
四、注入式AspectJ切面(各版本Spring)express
一、before advice 在方法執行前執行。
二、after returning advice 在方法執行後返回一個結果後執行
三、after throwing advice 在方法執行過程當中拋出異常後執行
四、around advuce 綜合執行以上三種狀況編程
一、建立通知:實現通知的這幾個接口,並實現其中的方法app
a)org.springframework.aop.MethodBeforeAdvice框架
b)org.springframework.aop.AfterReturningAdviceide
c)org.springframework.aop.ThrowsAdviceui
d)org.aopalliance.intercept.MethodInterceptor
e)org.springframework.aop.IntroductionInterceptor
二、定義切點和通知者:在Spring配製文件中配置這些信息
三、使用ProxyFactoryBean來生成代理
要想實現Spring AOP 僅僅針對某一指定的方法進行切面編程,而不是針對全部的方法進行切面編程,那麼須要指定切入點(pointcut) ,pointcut經過制定方法名進行攔截方法,同時pointcut必須advisor進行關聯。pointcut能夠經過指定徹底方法名或經過正則表達式進行匹配方法。
<bean id="namePointCut" class="org.springframework.aop.support.NameMatchMethodPointcut"> <property name="mappedName" value="insertTestStudent" /> </bean>
org.springframework.aop.support.NameMatchMethodPointcut:表示該切點經過直接經過徹底方法名匹配方法的,property中的value就是完整的方法名。
<bean id="addGuideIntegralAfterTesting" class="org.springframework.aop.support.JdkRegexpMethodPointcut"> <property name="pattern" value=".*insertTestStudent"/> </bean>
結合通知者advisor
<bean id="audienceAdvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor"> <property name="advice" ref="audienceAdvice" /> <property name="pointcut" ref="performancePointcut" /> </bean>
org.springframework.aop.support.DefaultPointcutAdvisor是個通知者類,他只是把通知關聯給切入點
聯合切入點是比較特殊的正則表達式切入點,他同時結合了切入點和通知者
<bean id="addGuideIntegralAfterTesting" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"> <property name="advice" ref="guideIntegralAfterAdvice" /> <property name="patterns"> <list> <value>.*insertTestStudent</value> </list> </property> </bean>
從AspectJ裏定義切點的方式就能夠看出AspectJ的切點語言是一種真正的切點表達語言。 類org.springframework.aop.aspectj.AspectJExpressionPointcut被用來定義AspectJ切點表達式
<bean id="performancePointcut" class="org.springframework.aop.aspectj.AspectJExpressionPointcut"> <property name="expression" value="execution(* Performer+.perform(..))" /> </bean>
經過使用DefaultPointcutAdvisor把切入點和通知者結合起來。咱們能夠利用特殊的通知者,把切點表達式定義爲通知者的一個屬性。對於AspectJ表達式來講,使用的通知者類是org.springframework.aop.aspectj.AspectJExpressionPointcutAdvisor:
<bean id="audienceAdvisor" class="org.springframework.aop.aspectj.AspectJExpressionPointcutAdvisor"> <property name="advice" ref="audienceAdvice" /> <property name="expression" value="execution(* Performer+.perform(..))" /> </bean>
通知者把通知與切點關聯起來,從而完整地定義一個切面。
切面在Spring裏是以代理方式實現的,因此仍然須要代理目標Bean才能讓通知者發揮做用,如下有兩種方式顯示代理,一經過ProxyFactoryBean方式或者經過自動代理。
<!--定義個聯合代理--> <bean id="addIntegralAutoProxyAop" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"> <property name="beanNames"> <list> <!--須要監聽的接口--> <value>guideStudentService</value> </list> </property> <property name="interceptorNames"> <list> <!-- 與第一個bean的id相匹配 --> <value>addGuideIntegralAfterTesting</value> </list> </property> </bean>
Spring的ProxyFactoryBean是個工廠Bean,用於生成一個代理,把一個或多個通知者應用到Bean
<bean id="duke" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="target" ref="dukeTarget" /> <property name="interceptorNames"> <list> <value>audienceAdvisor</value> </list> </property> </bean>
<!--定義個聯合代理--> <bean id="addIntegralAutoProxyAop" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"> <property name="beanNames"> <list> <!--須要監聽的接口--> <value>guideStudentService</value> </list> </property> <property name="interceptorNames"> <list> <!-- 與第一個bean的id相匹配 --> <value>addGuideIntegralAfterTesting</value> </list> </property> </bean>
<!-- 定義通知advice --> <bean id="guideIntegralAfterAdvice" class="com.rrtong.interceptors.GuideIntegralAfterAdvice" /> <!-- 定義pointcut和通知者advisor的聯合切入點和通知者 --> <bean id="addGuideIntegralAfterTesting" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"> <!-- 引用通知接口的實現類 --> <property name="advice" ref="guideIntegralAfterAdvice" /> <!-- 正則表達式匹切入點方法名 --> <property name="patterns"> <list> <value>.*insertTestStudent</value> </list> </property> </bean> <!-- 定義自動代理 --> <bean id="addIntegralAutoProxyAop" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"> <property name="beanNames"> <list> <value>guideStudentService</value> </list> </property> <property name="interceptorNames"> <list> <value>addGuideIntegralAfterTesting</value> </list> </property> </bean>
joinpoint就是程序執行過程當中可以插入到切面的一個點,這個點就是方法被調用時,異常拋出時,甚至字段被編輯時。切面代碼經過這個點插入到程序的通常流程中,從而添加新的行爲。
pointcut做用就是縮小切面通知範圍
http://blog.csdn.net/sin90lzc/article/details/7486145
http://blog.163.com/zzf_fly/blog/static/209589158201382314454298/
http://blog.csdn.net/topwqp/article/details/8695180