lqxue

          常用鏈接

          統(tǒng)計

          book

          tools

          最新評論

          Spring AOP處理日志

          Spring AOP處理日志

          AOP正在成為軟件開發(fā)的下一個圣杯。使用AOP,你可以將處理aspect的代碼注入主程序,
          通常主程序的主要目的并不在于處理這些aspect。AOP可以防止代碼混亂。 為了理解AOP
          如何做到這點,考慮一下記日志的工作。日志本身不太可能是你開發(fā)的主程序的主要任務(wù)。
          如果能將“不可見的”、通用的日志代碼注入主程序中,那該多好啊。AOP可以幫助你做到。
          Spring framework是很有前途的AOP技術(shù)。作為一種非侵略性的,輕型的AOP framework,你
          無需使用預(yù)編譯器或其他的元標簽,便可以在Java程序中使用它。這意味著開發(fā)團隊里只需
          一人要對付AOP framework,其他人還是象往常一樣編程。 AOP是很多直覺難以理解的術(shù)語的根源。
          幸運的是,你只要理解三個概念,就可以編寫AOP模塊。這三個概念是:advice,pointcut和advisor。
          advice是你想向別的程序內(nèi)部不同的地方注入的代碼。pointcut定義了需要注入advice的位置,通常
          是某個特定的類的一個public方法。advisor是pointcut和advice的裝配器,是將advice注入主程序
          中預(yù)定義位置的代碼。

          既然我們知道了需要使用advisor向主要代碼中注入“不可見的”advice,讓我們實現(xiàn)一個Spring AOP的例子。
          在這個例子中,我們將實現(xiàn)一個before advice,這意味著advice的代碼在被調(diào)用的public方法開始前被執(zhí)行。
          以下是這個before advice的實現(xiàn)代碼:

          代碼:
          package com.company.springaop.test;

          import java.lang.reflect.Method;
          import org.springframework.aop.MethodBeforeAdvice;

          public class TestBeforeAdvice implements MethodBeforeAdvice { //這里還有after,Exception,around等Advice
          /**
          *before 是在方法執(zhí)行之前執(zhí)行advice的內(nèi)容,around是在方法執(zhí)行之前和之后都得到了執(zhí)行
          *Exception是拋出異常的時候,可以使用aop的方法來統(tǒng)一處理業(yè)務(wù)的異常。
          ×在編程的時候,可以由專門的人處理業(yè)務(wù)的異常,其它人還是一樣的編程,不用考慮業(yè)務(wù)類異常的處理。
          */

            public void before(Method m, Object[] args, Object target)
            throws Throwable { //這里能用反射?
              System.out.println("Hello world! (by "
                  + this.getClass().getName()
                  + ")");
            }
          }
           


          接 口MethodBeforeAdvice只有一個方法before需要實現(xiàn),它定義了advice的實現(xiàn)。before方法共用三個參數(shù),它們提供了相當 豐富的信息。參數(shù)Method m是advice開始后執(zhí)行的方法。方法名稱可以用作判斷是否執(zhí)行代碼的條件。Object[] args是傳給被調(diào)用的public方法的參數(shù)數(shù)組。當需要記日志時,參數(shù)args和被執(zhí)行方法的名稱,都是非常有用的信息。你也可以改變傳給m的參數(shù), 但要小心使用這個功能;編寫最初主程序的程序員并不知道主程序可能會和傳入?yún)?shù)的發(fā)生沖突。Object target是執(zhí)行方法m對象的引用。

          在下面的BeanImpl類中,每個public方法調(diào)用前,都會執(zhí)行advice:

          代碼:
          package com.company.springaop.test;

          public class BeanImpl implements Bean {

            public void theMethod() {
              System.out.println(this.getClass().getName()
                  + "." + new Exception().getStackTrace()[0].getMethodName()
                  + "()"
                  + " says HELLO!");
            }
          }


          類BeanImpl實現(xiàn)了下面的接口Bean:

          代碼:
          package com.company.springaop.test;

          public interface Bean {
            public void theMethod();
          }

           

          雖然不是必須使用接口,但面向接口而不是面向?qū)崿F(xiàn)編程是良好的編程實踐,Spring也鼓勵這樣做。

          pointcut和advice通過配置文件來實現(xiàn),因此,接下來你只需編寫主方法的Java代碼:
          代碼:


          package com.company.springaop.test;

          import org.springframework.context.ApplicationContext;
          import org.springframework.context.support.FileSystemXmlApplicationContext;

          public class Main {

            public static void main(String[] args) {
              //Read the configuration file
              ApplicationContext ctx
                  = new FileSystemXmlApplicationContext("springconfig.xml");

              //Instantiate an object
              Bean x = (Bean) ctx.getBean("bean");

              //Execute the public method of the bean (the test)
              x.theMethod();
            }
          }

           

          我們從讀入和處理配置文件開始,接下來馬上要創(chuàng)建它。這個配置文件將作為粘合程序不同部分的“膠水”。讀入和處理配置文件后,我們會得到一個創(chuàng)建工廠ctx。任何一個Spring管理的對象都必須通過這個工廠來創(chuàng)建。對象通過工廠創(chuàng)建后便可正常使用。

          僅僅用配置文件便可把程序的每一部分組裝起來。
          代碼:

          <?xml version="1.0" encoding="UTF-8"?>
          <!DOCTYPE beans PUBLIC  "-//SPRING//DTD BEAN//EN" "

          <beans>
            <!--CONFIG-->
            <bean id="bean" class="org.springframework.aop.framework.ProxyFactoryBean">
              <property name="proxyInterfaces">
                <value>com.company.springaop.test.Bean</value>
              </property>
              <property name="target">
                <ref local="beanTarget"/>
              </property>
              <property name="interceptorNames">
                <list>
                  <value>theAdvisor</value>
                </list>
              </property>
            </bean>

            <!--CLASS-->
            <bean id="beanTarget" class="com.company.springaop.test.BeanImpl"/>

            <!--ADVISOR-->
            <!--Note: An advisor assembles pointcut and advice-->
            <bean id="theAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
              <property name="advice">
                <ref local="theBeforeAdvice"/>
              </property>
              <property name="pattern"> //pointcut?
                <value>com\.company\.springaop\.test\.Bean\.theMethod</value>
              </property>
            </bean>

            <!--ADVICE-->
            <bean id="theBeforeAdvice" class="com.company.springaop.test.TestBeforeAdvice"/>
          </beans>
           


          四個bean定義的次序并不重要。我們現(xiàn)在有了一個advice,一個包含了正則表達式pointcut的advisor,
          一個主程序類和一個配置好的接口,通過工廠ctx,這個接口返回自己本身實現(xiàn)的一個引用。 BeanImpl
          和TestBeforeAdvice都是直接配置。我們用一個唯一的ID創(chuàng)建一個bean元素,并指定了一個實現(xiàn)類。這
          就是全部的工作。advisor通過Spring framework提供的一個RegexMethodPointcutAdvisor類來實現(xiàn)。我
          們用advisor的一個屬性來指定它所需的advice-bean。第二個屬性則用正則表達式定義了pointcut,確保
          良好的性能和易讀性。 最后配置的是bean,它可以通過一個工廠來創(chuàng)建。bean的定義看起來比實際上要
          復(fù)雜。bean是ProxyFactoryBean的一個實現(xiàn),它是Spring framework的一部分。這個bean的行為通過一下
          的三個屬性來定義:

           


          屬性proxyInterface定義了接口類。

          屬性target指向本地配置的一個bean,這個bean返回一個接口的實現(xiàn)。

          屬性interceptorNames是唯一允許定義一個值列表的屬性。這個列表包含所有需要在beanTarget上執(zhí)行的advisor。

          注意,advisor列表的次序是非常重要的。

           

          Spring工具

          雖然你可以手工修改Ant構(gòu)建腳本,但使用SpringUI(譯注:SpringUI現(xiàn)在是Spring framework的一部分,并改名
          為spring-ide),使用Spring AOP變得很簡單,只要點點鼠標即可。你可以把SpringUI安裝成Eclipse的一個plug-in。
          然后,你只需在你的project上右擊鼠標,并選擇“add Spring Project Nature”。在project屬性中,你可以在“Spring
          Project”下添加Spring配置文件。在編譯前把下面的類庫加入project:aopalliance.jar,commons-logging.jar,
          jakarta-oro-2.0.7.jar和spring.jar。運行程序時你會看到下面的信息:

          ... (logging information)
          Hello world! (by com.company.springaop.test.TestBeforeAdvice)
          com.company.springaop.test.BeanImpl.theMethod() says HELLO!


          優(yōu)點和缺點

          Spring比起其他的framework更有優(yōu)勢,因為除了AOP以外,它提供了更多別的功能。
          作為一個輕型framework,它在J2EE不同的部分都可以發(fā)揮作用。因此,即使不想使用Spring AOP,
          你可能還是想使用Spring。另一個優(yōu)點是,Spring并不要求開發(fā)團隊所有的人員都會用它。
          學(xué)習(xí)Spring應(yīng)該從Spring reference的第一頁開始。讀了本文后,你應(yīng)該可以更好地理解Spring reference了。
          Spring唯一的缺點是缺乏更多的文檔,但它的mailing list是個很好的補充,而且會不斷地出現(xiàn)更多的文檔。


          (引自http://blogger.org.cn/blog/more.asp?name=littcricket&id=18341)




          posted on 2007-04-09 16:23 lqx 閱讀(943) 評論(0)  編輯  收藏


          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 阿鲁科尔沁旗| 海伦市| 万年县| 垦利县| 都兰县| 高唐县| 涟源市| 类乌齐县| 滁州市| 霍山县| 闻喜县| 化德县| 宣汉县| 黑龙江省| 阿合奇县| 湘潭县| 通化市| 茶陵县| 健康| 会东县| 津南区| 齐齐哈尔市| 苗栗县| 绥棱县| 娄底市| 元谋县| 勐海县| 石林| 综艺| 乌兰察布市| 汉川市| 宜宾县| 惠州市| 舟山市| 乐陵市| 海城市| 清河县| 达州市| 卫辉市| 土默特右旗| 孝义市|