瘋狂

          STANDING ON THE SHOULDERS OF GIANTS
          posts - 481, comments - 486, trackbacks - 0, articles - 1
            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

          spring aop

          Posted on 2010-09-07 22:03 瘋狂 閱讀(2128) 評(píng)論(0)  編輯  收藏 所屬分類: java spring

          AOP的術(shù)語

          z

          切面(aspect)

                  切面是你要實(shí)現(xiàn)的交叉功能。就是通知和切入點(diǎn)的結(jié)合。通知和切入點(diǎn)共同定義了關(guān)于切面的全部內(nèi)容:它的功能、在何時(shí)和何地完成功能。

          通知(Advice)

                通知定義了切面是什么以及何時(shí)使用。除了描述切面要完成的工作,通知還解決了何時(shí)執(zhí)行這個(gè)工作的問題。應(yīng)該在一個(gè)方法被調(diào)用之前?之后?或者拋出異常時(shí)。

          切入點(diǎn)(pointcut)
                  如果說通知定義了切面的"什么"和"何時(shí)",那么切入點(diǎn)就定義了"何地"。


          連接點(diǎn)(joinpoint)

                連接點(diǎn)是應(yīng)用程序執(zhí)行過程中能夠插入切面的地點(diǎn)。這些點(diǎn)可以是方法被調(diào)用時(shí)、異常拋出時(shí)、甚至字段被編輯時(shí)。

          引入(Intrduction)

                  引入允許你為已經(jīng)存在的類添加新方法和屬性。比如一個(gè)Auditable通知類,記錄對(duì)象在最后一次被修改時(shí)的狀態(tài)。只需要一個(gè)setLastModified(Date)方法,和一個(gè)實(shí)例變量來保存這個(gè)狀態(tài)。這個(gè)新方法和實(shí)例變量就可以被引入到現(xiàn)有的類,從而在不修改它們的情況下,讓他們具有新的行為和狀態(tài)。

          目標(biāo)對(duì)象(Target)

                  目標(biāo)對(duì)象是被通知的對(duì)象。

          代理(Proxy)

                   代理是將通知應(yīng)用到目標(biāo)對(duì)后創(chuàng)建的對(duì)象。

          織入(weaving)

                    織入是將切面應(yīng)用到目標(biāo)對(duì)象從而創(chuàng)建一個(gè)新的代理對(duì)象的過程。 在目標(biāo)對(duì)象的生命周期里有多個(gè)機(jī)會(huì)發(fā)生織入過程。比如編譯時(shí)、類加載時(shí)、運(yùn)行時(shí)。


           

          通知、切點(diǎn)、通知者

          通知

          在Spring AOP里有5中類型的通知,分別由一個(gè)接口進(jìn)行定義

          Before(前)

          org.springframework.aop.MethodBeforeAdvice

          After-returning(返回后)

          org.springframework.aop.AfterReturningAdvice

          After-throwing(拋出后)

          org.springframework.aop.ThrowsAdvice

          Around(周圍)

          org.aopalliance.intercept.MethodInterceptor

          Introduction(引入)

          org.springframework.aop.IntroductionInterceptor


          <bean id="audienceAdvice" class="com.springidol.AudienceAdvice"></bean>

          //AudienceAdvice類實(shí)現(xiàn)了3中不同的3中不同類型的AOP通知。

          Public class AudienceAdvice implements MethodBeforeAdvice,AfterReturningAdvice,ThrowsAdvice{

          //前通知要求實(shí)現(xiàn)的方法

          public void before(Method method,Object[] args,Object target) throws Throwable{


          }


          //返回后通知要求實(shí)現(xiàn)的方法,Object returnValue表示被調(diào)用方法的返回值

          public void  afterReturning(Object returnValue,Method method,Object[] args,Object target) throws Throwable{


          }


          //拋出后通知不需要實(shí)現(xiàn)任何方法,它只是一個(gè)標(biāo)記接口,告訴spring相應(yīng)的通知要求處理被拋出的異常,除最后一個(gè)參數(shù)外,其他參數(shù)都是可選的

          public void afterThrowing(Method method,Object[] args,Object target,NullPointerException e) throws Throwable{


          //當(dāng)發(fā)生NullPointerException 時(shí),記錄日志

          LOGGER.error("NPE thrown from "+method.getName());

          }


          }


          其中的Method method參數(shù),表示要使用這個(gè)通知的方法,第二個(gè)參數(shù)Object[] args是方法被調(diào)用時(shí)要傳遞的參數(shù)。最后一個(gè)是方法調(diào)用的目標(biāo)也就是被調(diào)用方法所在的對(duì)象。

          //周圍通知相當(dāng)于前通知、后通知、拋出后通知的結(jié)合。

          Public class AudienceAdvice implements MethodInterceptor{

          Public Object invoke(MethodInvocation invocation) throws Throwable{

          try{

          ..............................    //在方法調(diào)用之前

          Object returnValue=invocation.proceed();    調(diào)用目標(biāo)方法

          .............................    //在方法調(diào)用之后

          }catch(PerformanceException e){

          .............................    /在出現(xiàn)異常之后

          }

          }

          }


          切點(diǎn)

          1.正則切點(diǎn)


          切點(diǎn)的作用主要在于選擇需要使用通知的方法,比如下面的正則表達(dá)式切點(diǎn):

          <bean id="performancePointcut"                      class="org.springframework.aop.support.JbkRegexpMethodPointcut">

          <property name="pattern" value=".*perform" />

          </bean>


          Pattern屬性用于制定方法匹配所使用的切點(diǎn)模板,本例中被設(shè)置為一個(gè)正則表達(dá)式,它應(yīng)該匹配任何類里名為perform的方法。


          定義切點(diǎn)后,把切點(diǎn)與通知關(guān)聯(lián)


          <bean id="audienceAdvisor"                     class="org.springframework.aop.support.DefaultPointcutAdvisor">

          <property name="advice" value="audienceAdvice" />

          <property name="pointcut" value="performancePointcut" />

          </bean>


          DefaultPointcutAdvisor是一個(gè)通知者類,它只是把通知關(guān)聯(lián)到一個(gè)切點(diǎn)


          也可以使用RegexpMethodPointcutAdvisor是一個(gè)特殊的通知者類,可以在一個(gè)Bean里面定義切點(diǎn)和通知者

          <bean id="audienceAdvisor"                     class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">

          <property name="advice" value="audienceAdvice" />

          <property name="pattern" value=".*perform" />

          </bean>


          2.定義AspectJ切點(diǎn)


          正則表達(dá)式雖然可以作為切點(diǎn)定義語言來使用,但是它并不是針對(duì)切點(diǎn)而創(chuàng)建的,其主要用途還是文本解析。AspectJ里定義切點(diǎn)的方法就可以看出AspectJ的切點(diǎn)語言是一種真正的切點(diǎn)表達(dá)式語言。


          <bean id="performancePointcut"                     class="org.springframework.aop.aspectj.AspectJExpressionPointcut">

          <property name="expression" value="execution(* Performer+.perform(..))" />

          </bean>


          可以使用DefaultPointcutAdvisor把它和通知關(guān)聯(lián)起來,就像前面一樣。同樣,也可以設(shè)置一個(gè)特殊的通知者

          <bean id="audienceAdvisor"                     class="org.springframework.aop.aspectj.AspectJExpressionPointcutAdvisor">

          <property name="advice" value="audienceAdvice" />

          <property name="expression" value="execution(* *.perform(..))" />

          </bean>

          execution* *.perform(..)) 

          execution表示執(zhí)行方法時(shí),* *表示任意返回類型,.perform表示perform方法,(..)表示任意參數(shù)設(shè)置


          使用ProxyFactoryBean


          <bean id="duke"

                    class="org.springframework.aop.framework.ProxyFactoryBean">

          <property name="proxyInterfaces">

                      <value>genericdaotest.dao.PersonDao</value>

                  </property>

                  <property name="target">

                      <bean parent="abstractDaoTarget">

                          <constructor-arg>

                              <value>genericdaotest.domain.Person</value>

                          </constructor-arg>

                      </bean>

                  </property>

                   <property name="interceptorNames">

                       <list>

                           <value>audienceAdvisor</value>

                       </list>

                   </property>

            </bean>


          Spring里面的ProxyFactoryBean是個(gè)工廠Bean,用于生成一個(gè)代理,把一個(gè)或者多個(gè)攔截者(和通知者)應(yīng)用到Bean,有target、interceptorNames、proxyInterfaces三個(gè)屬性,后兩個(gè)都是數(shù)組屬性target表示要代理的對(duì)象

          interceptorNames屬性告訴ProxyFactoryBean哪個(gè)通知者要應(yīng)用于被代理的

          beanproxyInterfaces告訴ProxyFactoryBean代理應(yīng)該實(shí)現(xiàn)哪個(gè)接口。本例中代理的是genericdaotest.dao.PersonDao接口

          target告訴ProxyFactoryBean,哪個(gè)Bean是代理。



          ----------------以上轉(zhuǎn)載自:http://bhsc.happy.blog.163.com/blog/static/1043895522008111144158773/


          主站蜘蛛池模板: 固始县| 报价| 宁陵县| 晋宁县| 长寿区| 望都县| 句容市| 宁蒗| 大同市| 新晃| 孝昌县| 尚志市| 千阳县| 永康市| 从江县| 正蓝旗| 绵竹市| 牟定县| 讷河市| 盐山县| 峡江县| 平南县| 西华县| 合肥市| 万安县| 洮南市| 颍上县| 苗栗市| 晋中市| 延川县| 电白县| 宿松县| 克什克腾旗| 星子县| 轮台县| 阳新县| 兴城市| 星座| 宁城县| 英吉沙县| 铅山县|