邊城愚人

          如果我不在邊城,我一定是在前往邊城的路上。

            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
            31 隨筆 :: 0 文章 :: 96 評論 :: 0 Trackbacks

          ??? ??? 在結束了上一篇Spring 1.x中AOP的使用之后,我又馬不停蹄的打開Eclipse,做著Spring2.X下了AOPSample。在上一篇文章中的配置過程中,由于對自動代理不是很熟,出現了循環引用的異常信息。當初在閱讀PicoContainer源碼時看到循環引用不以為然,后來在學習AspectJ時小有印象,這次在折騰了半個多小時后可加深了印象。

          ??? ??? 好啦,閑言少敘,奔向文本的主題吧。和Spring1.X相比,Spring2.X使用AspectJ的語法來聲明AOP,這使得它更“標準”,更靈活了。還是那句話,如果你不了解AspectJ并且打算使用Spring2.XAspectJAOP,那就學學AspectJ吧,這方面的書還是很多了。

          ??? ??? Spring2.X下的切面有兩種實現方式,一種是以Java文件定義切面(其只是普通的Java類),然后在配置文件中聲明定義的切面;另一種是在Java類中引入和AOP相關的元數據(注釋)。

          ??? ??? 先介紹第一種配置方式。需要指出的是,Spring2.Xbeans名稱空間和Spring1.X有所不同,它采用了Schema而不是DTD(也可采用DTD方式,具體的請參考文檔)。還是引入毫無意義的日志切面,定義的切面類LogingAspect 如下:


          public ? class ?LogingAspect?{

          public ? void ?logMethod(JoinPoint?jp){

          ????????System.err.println(jp.getTarget().getClass());

          ????????System.err.println(jp.getSignature().getName());

          }

          }

          ??? ??? 同時在配置文件中如下配置:


          < bean?id = " logAspectTarget " ? class = " hibernatesample.service.util.LogingAspect " ></ bean >

          < aop:config >

          < aop:aspect?id = " logAspect " ?ref = " logAspectTarget " >

          < aop:pointcut?id = " businessService " ?expression = " execution(*?hibernatesample.service.*.*(..)) " />

          < aop:after?pointcut - ref = " businessService " ?method = " logMethod " />

          </ aop:aspect >

          </ aop:config >

          ???????對于上面的切面,切入點businessService是在配置文件中聲明的,其表達式采用了 AspectJ的語法,LogingAspect?類中logMethod(JoinPoint jp)方法根據配置文件信息可知其是after通知,方法的JoinPoint參數不是必須的,它是來自于AspectJ的實用類,這里用它不過輸出一些和連接點有關的信息。當然,在Spring2.X中,切入點和通知能更靈活的使用,我們可以如AspectJ一樣傳遞參數給通知。如果需要在Service中引入事務功能,需要如下配置事務通知:


          < tx:advice?id = " txAdvice " ?transaction - manager = " transactionManager " >

          < tx:attributes >

          < tx:method?name = " get* " ?read - only = " true " />

          < tx:method?name = " find* " ?read - only = " true " />

          < tx:method?name = " * " />

          </ tx:attributes >

          </ tx:advice >


          < aop:config >

          < aop:pointcut?id = " demoServiceMethods " ?expression = " execution(*?hibernatesample.service.*.*(..)) " />

          < aop:advisor?advice - ref = " txAdvice " ?pointcut - ref = " demoServiceMethods " />

          < aop:aspect?id = " logAspect " ?ref = " logAspectTarget " >

          < aop:pointcut?id = " businessService " ?expression = " execution(*?hibernatesample.service.*.*(..)) " />

          < aop:after?pointcut - ref = " businessService " ?method = " logMethod " />

          </ aop:aspect >

          </ aop:config >



          ??? ??? 完成上面的工作相當于完成了 Spring1.X 自動代理。 我們接下來需要定義的任何 Service Bean 都可以很純粹很純粹了:


          < bean? id ="accountService" ?class ="hibernatesample.service.impl.AccountServiceImpl" >

          < property? name ="accountDAO" ?ref ="accountDAO" ></ property >

          </ bean >


          ??? ??? 第二種實現 AOP 的方式和第一種相比,只是在 LogingAspect 中加入了注釋,而省去了配置文件中和 LogingAspect 相關的配置。重新編寫的 LogingAspect 如下:


          @Aspect

          public ? class ?LogingAspect?{

          @Pointcut(
          " execution(*?hibernatesample.service.*.*(..)) " )

          public ? void ?businessService(){}

          @After(
          " businessService() " )

          public ? void ?logMethod(JoinPoint?jp){

          System.err.println(jp.getTarget().getClass());

          System.err.println(jp.getSignature().getName());

          }

          }

          ??? ??? 而簡化后的配置文件可以去除上面的如下和 logAspect 相關的配置信息:


          < aop:aspect? id ="logAspect" ?ref ="logAspectTarget" >

          < aop:pointcut? id ="businessService" ?expression ="execution(*?hibernatesample.service.*.*(..))" />

          < aop:after? pointcut-ref ="businessService" ?method ="logMethod" />

          </ aop:aspect >

          < bean? id ="logAspectTarget" ?class ="hibernatesample.service.util.LogingAspect" ></ bean >

          ??? ??? 還沒有完,為了使 Spring 應用 LogingAspect? 的注釋,需要在配置文件中添上

          ??? ??? <aop:aspectj-autoproxy/>


          ???? ??? 如果覺得事務的配置沒有使用注釋更簡潔(我倒不會有這樣的想法,畢竟在配置文件中聲明的事務只是那么固定的幾段,除非作用于類上的事務邏輯上很復雜),也可以使用Spring提供的事務注釋作用于類文件上,這可是更細粒度的事務聲明了。

          ??????坦率的說,由于時間有限,該文寫的比較粗糙。對于Spring AOP有興趣并有疑問的朋友,可以參考Spring的文檔,它的文檔做的還是不錯的。
          posted on 2007-08-30 08:42 kafka0102 閱讀(2299) 評論(2)  編輯  收藏 所屬分類: FrameworkAOP

          評論

          # re: Spring2.X中AOP的使用 2007-08-30 12:40 JAVA面試題
          學習了  回復  更多評論
            

          # re: Spring2.X中AOP的使用 2007-08-30 18:15 光榮之翼
          收藏  回復  更多評論
            

          主站蜘蛛池模板: 竹山县| 保德县| 阳东县| 武穴市| 泰安市| 松潘县| 永和县| 富锦市| 潍坊市| 青阳县| 孝昌县| 樟树市| 平泉县| 新宁县| 武城县| 准格尔旗| 乌审旗| 宾阳县| 富裕县| 陕西省| 汪清县| 荆门市| 平罗县| 含山县| 安陆市| 尖扎县| 磐石市| 枝江市| 皋兰县| 河北省| 莒南县| 吉水县| 郁南县| 三门峡市| 壤塘县| 张家界市| 道孚县| 亳州市| 和平区| 同心县| 淮滨县|