SlideShare a Scribd company logo
。一之點重的節章個這是也           用使何如解了您讓,心
                              Spring AOP
核的賴依所能功 子或架框子些一中        是也              而,術
                                   Spring     Spring AOP
技種一的 現實是   AOP   ,型 模 計 設 個 兩 的 成 相 輔 相 以 可 是
                     S pring AOP
們 它,觸 抵 互 相 不 並)                 ( 跟
                    OOP O bject-oriented programming           AOP
                         。釋解得獲將都中節章個這在,詞名
的關相 與樣各式各上以,)
      AOP                        (合縫的式程用應與及計設
                               W eave
的 Aspect 在重著                            ,  為之稱件
                 A spect-oriented programming     Aspect
物 殊 特 的 樣 這,件 物 個 一 為 計 設 來 出 立 獨       Crossing-cutting concerns
將,                     為 稱 輯 邏 的 樣 這 ,)
   Cross-cutting concerns                 、     S ecurity   Logging
如例(輯邏務服統系的關無輯邏務商與入插中程流的務服個一在
                                            Spring AOP
    4
Spring 2.0   良信林(冊手術技            – http://openhome.cc   )

  4.1 AOP 入門
   過觸接未尚於對,
      AOP                                    名全
                    Aspect-oriented programming                    AOP   的
        是像,解理以難人令詞名語術的象抽多許中 ,說來人
             A OP                                             Cross-cutting
  (制機理代從先將,中節小個這在,等
  concerns     A spect    W eave        、       、                   S pring
  紹介 中 從 , 式 程 範 示的單 簡 且 際 實 個 一 看 來 ) 式 方 種 一 的 現 實
       AOP                                                            AOP
                                        。語術種各與念觀的
  4.1.1 從代理機制初探 AOP

  子例的見常單簡個一從先,邊一到放詞名寫縮文英個這 將先且暫
                    AOP
  需常很中式程,作動)    (誌日有含中當子例個這,題議個一看來           L ogging
  為作是或,程過作運式程視檢後事在便以,錄記下作件事或作動些某為要
                               。訊資的時錯除
  ,息訊誌日下留時法方些某行執在要需您當,子例的單簡最個一看來
                     : 寫 撰下如 會 能 可 您 , 的 覺 直
  package onlyfun.caterpillar;

  import java.util.logging.*;

  public class HelloSpeaker {
      private Logger logger =
              Logger.getLogger(this.getClass().getName());

      public void hello(String name) {
          //   錄記下留時始開行執法方
               錄
          logger.log(Level.INFO, "hello method starts....");
          //        能功要主式程
          System.out.println("Hello, " + name);
          //   錄記下留前畢完行執法方
               錄記下留前畢完行執法方
          logger.log(Level.INFO, "hello method ends....");
      }



4 2
4 3
            :面介              IHello
                  個一義定先首,說來子例的際實個舉
          。責職關相務商留保僅以可就中當件物理代被此如,件
  物的理代被叫呼再候時的要需在並,務服關相等誌日現實以可中件物理
  代在,面介個一同現實須必件物理代被與件物理代,中現實的理代態靜在
                              理代態靜
      。)    D ynamic proxy
                        (理代態動與)        S tatic proxy
                                               ( 理代 態靜:式方
 理代種兩論討邊這在,題問個這決解來制機) ( 理 代用使以可            P roxy
                             。 去 移 中 式 程 的 有既從 務 服 關 相 些 這 將 的
 單簡法無您,碼式程的作動誌日下留有所改修要需將麼那,務服的)等理
 管易交、查檢限權或(誌日要需再不若,法寫的上以用使,面方一另
 。 碼式程 的 務 服 或 作 動 的 關相不 責 職 件 物 與 些 這 於少還 許 或 , 碼 式 程 的 佔
 所責職的身本件物,責職的有負該身本件物了淆混至甚,重加形更擔負的
 件物得使會,)等等理管易交、查檢限權如例(中之件物了入混也作動關
 相 的 責 職 身 本 件 物 非 些 一 有 , 作 動 誌 日 有 只 不)   S ervice
                                               (務 服 的 要 需 果 如
 。大加度難困的碼式程誌日護維得使這,碼式程的作動誌日些這寫撰處到您
 成造必勢法寫的上以,求需有都處到作動的誌日種這中式程果如想想
                                        。責職的外額了加增              Speaker
  Hello-
       得使這,)字文等         "Hello"
                             示顯(輯邏務商         HelloSpeaker
                                                     於屬不並作
 動 個 幾 這 的 誌 日,說 來     HelloSpeaker
                                 於 對,中 別 類     H elloSpeaker
                                                      )            cutting
  C ross-
       (入切橫碼式程行幾這的誌日而然,作動誌日上加後前的行執法
 方在,計設式程的上以如是就法作的單簡最,錄記下留能都時畢完行執與
 始開行執法方望希您,時法方               hello()
                                 行執當,中別類            HelloSpeaker
                                                         在
                                                                        }
  Chapter 4 Spring AOP
Spring 2.0   良信林(冊手術技         – http://openhome.cc       )

      StaticProxyDemo                                            IHello.java
  package onlyfun.caterpillar;

  public interface IHello {
      public void hello(String name);
  }


      的輯邏務商現實讓後然           HelloSpeaker   現實別類    IHello   :如例,面介
  StaticProxyDemo                                          HelloSpeaker.java
  package onlyfun.caterpillar;

  public class HelloSpeaker implements IHello {
      public void hello(String name) {
          System.out.println("Hello, " + name);
      }
  }


      ,中其入插碼式程的誌日何任有沒在現中別類
                   HelloSpeaker 在,到看以可
      介   現實要也樣同件物理代,中之件物理代至放被將現實的務服誌日                              IHello
                                 :如例,面
      StaticProxyDemo                                        HelloProxy.java
  package onlyfun.caterpillar;

  import java.util.logging.*;

  public class HelloProxy implements IHello {
      private Logger logger =
              Logger.getLogger(this.getClass().getName());

        private IHello helloObject;

        public HelloProxy(IHello helloObject) {
            this.helloObject = helloObject;
        }



4 4
Chapter 4 Spring AOP




      public void hello(String name) {
          //    務服誌日
          log("hello method starts....");

             // 輯邏務商行執
             helloObject.hello(name);

             // 務服誌日
             log("hello method ends....");
      }

      private void log(String msg) {
          logger.log(Level.INFO, msg);
      }
}


    誌 日 排 安 以 可 後 前 輯 邏 務 商 現 實 正 真,中 法 方
          HelloProxy       hello()        的別類 在
                  。件物理代用使何如看看來式程試測個一寫撰際實,務服
    StaticProxyDemo                                 ProxyDemo.java
package onlyfun.caterpillar;

public class ProxyDemo {
    public static void main(String[] args) {
        IHello proxy =
            new HelloProxy(new HelloSpeaker());
        proxy.hello("Justin");
    }
}


    物理代被個一它給須必時件物理代構建,件物理代是的行執叫呼中式程
    來,面介   為面介作操換轉須必,時件物理代的回取作操在得記,件                IHello
                         :果結的行執際實下一看



                                                                 4
4 6
               。理原本基的理代解了您讓在是,的目
的理代態靜紹介邊這在,任勝法無就時大稍模規式程在理代態靜,理代行
進法方個每為要必勢,多很法方的理代要果如且而,件物的型類種一於務
服只面介個一的件物理代,的到看所您如而然,例範本基的理代態靜是這
                     程流作運的制機理代          4.2   圖
                        :程流作運的制機理
代出看步一進更來式方的解圖從以可,責職的它於心專以可                              HelloSpeaker
,作動誌日入介必不時寫撰在            HelloSpeaker
                   得使這,作動的誌日上加後前
其在並,hello()
       行執來          HelloSpeaker
                 的正真理代將      件物理代                 HelloProxy
              果結行執案專       4.1 StaticProxyDemo    圖
              )   – http://openhome.cc    良信林(冊手術技             Spring 2.0
Chapter 4 Spring AOP




     文              在現出都何為息訊誌日的 圖:問會人多很
                     4.1                      " Hello, Justin"
     ? 嗎 錯 有 果 結 行 執 例 範 ?) 後 之 在 是 許 也 果 結 的 行 執 您 (前 之 字
     不並作動誌日,行進來緒行執個一另由是作動的誌日,道知要
     執有實確作動誌日於在點重的例範,程流式程)入介或(響影
     來用是不也作動誌日,序順的現出台控主於息訊在是不而,行
     順的息訊現出台控主到看想的真果如。用之序順行執式程測預
     全份部的誌日將麼那,序順叫呼的法方與件物中式程合符,序
                                       。可即出輸準標成改部

                                                     理代態動
  件 物 定 特 為 必 不 您, 的 能 功 理 代 態 動 發 開 助 協 可 了 入 加 後 之
    JDK 1.3                                    API      在
  者理處個一得使以可,理代態動用使,件物理代的定特寫撰法方與
  作實須必計設別類的者理處個一,先首。件物個各於務服)
    H andler                                            (
  java.lang.reflect.InvocationHandler
  計 設 如 例,明 說 行 進 來 例 實 以,面 介
       LogHandler                        :別類           個一
 DynamicProxyDemo                                    LogHandler.java
package onlyfun.caterpillar;

import java.util.logging.*;
import java.lang.reflect.*;

public class LogHandler implements InvocationHandler {
    private Logger logger =
            Logger.getLogger(this.getClass().getName());

   private Object delegate;

   public Object bind(Object delegate) {
       this.delegate = delegate;
       return Proxy.newProxyInstance(
                          delegate.getClass().getClassLoader(),




                                                                  4 7
Spring 2.0     良信林(冊手術技          – http://openhome.cc     )

                                   delegate.getClass().getInterfaces(),
                                   this);
       }

       public Object invoke(Object proxy, Method method,
                            Object[] args) throws Throwable {
           Object result = null;

            try {
                log("method starts..." + method);

                  result = method.invoke(delegate, args);

                logger.log(Level.INFO, "method ends..." + method);
            } catch (Exception e){
                log(e.toString());
            }

            return result;
       }

       private void log(String message) {
           logger.log(Level.INFO, message);
       }
  }


      物理代個一立建法方態靜              用使是念概的要主
                          Proxy.newProxyInstance()
      的立建所作操以可您後之,面介的理代要所知告須必時件物理代立建,件
      ,法方     的          行執會時作操次每在,件物理代 InvocationHandler       invoke()
      的行執要上際實,數參行執與稱名法方的件物理代被入傳會法方
      invoke()
      ,作動誌日上加後前         在您,
                 method.invoke()   由交法方   method.invoke()
           。果結傳回的後過行執法方際實是件物的回傳
      method.invoke()

             :如例,面介的理代要所義定須必樣同,理代態動現實要




4 8
Chapter 4 Spring AOP




    DynamicProxyDemo                                           IHello.java
package onlyfun.caterpillar;

public interface IHello {
    public void hello(String name);
}


    的輯邏務商現實讓後然            HelloSpeaker   現實別類   IHello   :如例,面介
    DynamicProxyDemo                                     HelloSpeaker.java
package onlyfun.caterpillar;

public class HelloSpeaker implements IHello {
    public void hello(String name) {
        System.out.println("Hello, " + name);
    }
}


    介       的中案專                      前之跟這,了到現發許或您的尖眼
                                     StaticProxyDemo               IHello
    。現 呈 整 完 的 例 範 了 為 是 來 出 寫 撰 邊 這 在,容 內 的 同 相 是
         H elloSpeaker                               、面
    定綁來法方           的             用使要您,式程的試測個一寫撰來下接
                                         LogHandler       bind()
                                            :示所下如,件物理代被
DynamicProxyDemo                                            ProxyDemo.java
package onlyfun.caterpillar;

public class ProxyDemo {
    public static void main(String[] args) {
        LogHandler logHandler = new LogHandler();

           IHello helloProxy =
                   (IHello) logHandler.bind(new HelloSpeaker());
           helloProxy.hello("Justin");
     }
}




                                                                            4
4 1
。碼 式程行一 何任改 修需不 身本式程 用應而 ,離脫 中式 程用應 從 接 直                                Aspect
些這將以可又,候時的務服關相要需不而,務服供提中之式程用應入介以
可,候時的要必在,外之式程用應於立獨以可                          Aspect
                                         ,下 之 計 設 的 好 在
                                          。 為即詞名寫縮         AOP
,Aspect-oriented programming
                         的謂所是就這,件物             的楚清責職個   Aspect
一的件物務商定特入介不、用通為計設)                         C ross-cutting concerns
                                                   (作動些
這將 您 , 務 服 或 作 動 的類這 等 誌 日 是 像 以 可 的 指 所       的中      Aspect        AOP
                            。)            A spect
                                       (面切為之稱件物的樣這
, LogHandler是或       HelloProxy
                         的範 示 中 例 範 前 之是像 , 件 物 務 服 個 一 為
計設,來出取提務任或作動的關無輯邏務商與等誌日將件物理代用使
。) C ross-cutting concern
                    (點 切 關切橫為之稱中 在作動的樣這誌日            AOP
,中程流行執式程的             HelloSpeaker
                           入)           C ross-cutting
                                          (切橫碼式程的誌日
            AOP
,說 來語術的 在,重加責職的                      HelloSpeaker
                                       得使這,作動誌日入插須
必卻,字文呼招示顯是責職的身本                      H elloSpeaker
                                       ,中子例的頁 如                    4.2
                                  AOP
                    ?係關何有 與子例個這,上題議的 到回                          AOP
                  。在存的作動誌日到識意用不它,作動的誌日於關有何
任入插用不也         HelloSpeaker
                      而,面介與件物定特於務服再不                            LogHandler
                 果結行執的案專       4.3 DynamicProxyDemo     圖
                                                     :果結的行執下一看來
                 )   – http://openhome.cc     良信林(冊手術技             Spring 2.0
4 11
                                                  :的純單很是
 程 流 務 商 的 來 原 如 例,涵 意 的     Cross-cutting concerns
                                               出調強可明說片圖以
 。  Cross-cutting concerns
                        為之稱被中語術的 在作動些這,中之程流 AOP
 理 處 的 件 物 個 各 至 插 安 到 見 被 常 中 之 式 程 用 應 些 一 在 ,)    (務服的  S ervice
 面層統系等)       T ransaction
                       (易交、查檢)           S ecurity
                                             (全安如,作動的類這
 誌 日 於 似 類 外 另,中 之 程 流 務 商 的 責 負 所 身 本       HelloSpeaker
                                                  至 入)                cutting
 C ross-
      (切橫被先原作動的誌日,中子例的案專                         DynamicProxyDemo
                                                        在
                                                     Cross-cutting concern
                             AOP
      : 念 觀 與 語 術 的 紹 介 以 照 對 一 逐 來,例 範 的 制 機 理 代 紹 介
 前之以將邊這,義意詞名其解理易容不並上面字從單,象抽於過都語術詞
 名多許的 於關有,  AOP          Aspect-Oriented Programming
                                       為名全                             AOP
                                             4.1.2 AOP 觀念與術語
               。詞名文中的服信人令更無有看後日待留,題問詞名
           的譯翻文中將,現呈來語術詞名文英的本原 以將,中節章                AOP
           的來下接此因,詞名譯翻文中的一統個有沒也在現語術詞名文
           英些這且而,口拗很在實文中成翻要語術詞名文英關相的                                  AOP
 Chapter 4 Spring AOP
4 12
專 DynamicProxyDemo
           在 如 例,改 修 的 何 任 作 用 不 件 組 用 重 可 的 中 式 程 用
應,離脫中式程用應從上馬以可也,候時的務服要需不,上之式程用應至
)   (合縫,候時的務服該要需在,來出立獨中程流務商從之將,認
  W eave
辨的   Aspect
      於重著中 在。例實體具個一的     AOP          是就語術的            Aspect            AOP
在別類      L ogHandler
         ,別類                 LogHandler
                       個一為計設作動的誌日將,中案專
DynamicProxyDemo
          在如例。                  Aspect
                     為之稱件物些這,件物的用重可立獨
個 各 計 設,來 起 集 收        Cross-cutting concerns
                           的中之輯邏務商個各於落散將
                                                                       Aspect
                                          。雜複為更寫撰的式程
或 輯 邏 的 身 本 件 物 務 商 得 使,中 之 輯 邏 務 商 於 雜 混               Cross-cutting concerns
,面方一另,譯編新重後然,碼式程的務服誌日寫撰有所改修須必則,務
服該除移是或改修能功誌日的中件物將要天今您若,高增本成的式程護維
得 使 會,中 程 流 之 件 物 的 務 商 某 責 負 在 寫 撰 接 直 若               Cross-cutting concerns
                               二之解圖      4.5 AOP   圖
             :念概的           與               Cross-cutting concerns     cutting
Cross-
   出示表解圖下以用使可則,段片式程查檢全安、誌日的關相入
寫的生生硬被像中碼式程的件物,務服等查檢全安與誌日入加要了為在現
                               一之解圖      4.4 AOP   圖
                  )    – http://openhome.cc        良信林(冊手術技           Spring 2.0
4 13
                                              。後前的法方
 至用應要       Advice
              些哪明說,        寫撰中   Pointcut   或檔義定在以可 Annotation
 您, 說 的 體 具 中       Spring 2.0
                   在。 務 服 供 提 上 式 程 用 應 至 合 縫    將, 時              Advice
 式示表    Pointcut
              合符法方的叫呼當,             的趣興感了義定 Jointpoint                 Pointcut
                                                                       Pointcut
                                 。候時的生發外例個某中法方是或
 ,) 有 都 者 兩 或 (後 之 或 前 之 行 執 被 法 方 個 某 是 能 可 機 時 行 執,                 Jointpoint
 的法方援支只            S pring
                  。機時的行執被中式程用應在                     是就,說來   Advice
 體 具,  Joinpoint
              為之稱機時或點的程流務商入加時行執式程用應在                                        Advice
                                                                       Joinpoint
                                                                     。務服的供
 提要所或為行的             Cross-cutting concerns
                  了括包中                                   A dvice   。例實體具個一
 的 Advice
      是就,法方    的    中案專  invoke()    LogHandler            DynamicProxyDemo
 是像,的作實何如是碼式程誌日括包會中                                      Advice    ,言而作動的
 誌日以。     Advice
         為之稱作實體具的                      Cross-cutting concerns       對中當     Aspect
                                                                            Advice
                                 。合耦生發架框式程用應的前目與
 而務服些某了入加前目為因會不而,中之式程用應的它其至用應件組些這
 將以可您,性用重的件組些這高提可而因,中之件組式程用應的用重可在
            API
 現出會不 的關相務服與,說的體具,在存否是件物的務服供提道知用
                      AOP
 不 它,式 方 計 設 的 以,說 來 件 組 的 用 重 可 中 式 程 用 應 於 對,面 方 一 另
                           。碼式程的身本改修用不並時務服誌日要
 需 它 在,件 組 的 用 重 可 中 式 程 用 應 是 就 色 角 的 表 代 所     的中案       HelloSpeaker
 Chapter 4 Spring AOP
Spring 2.0   良信林(冊手術技             – http://openhome.cc           )

    Target

    個一     Advice    如例,件物標目或象對的用應被                     DynamicProxyDemo        中案專
     的 HelloSpeaker 的    中     是就
                               LogHandler      Advice     Target   。
    Introduction

    類該改修用不而,為行加增其為以可      ,別類的存現個一於對
                               I ntroduction
    期時行執在,別類的成完譯編、寫撰已個某為以可,說的體具,式程的別
        。碼式程行一何任增新或改修用不而,為行或法方些一入加態動
    Proxy

        E xpert One-on-One J2EE Development WIthout EJB
       ,中 書 一》                                           《在                        R od
    的要主個五有作實的 ,到提有中章八第在
    Johnson     J uergen Hoeller                    、      A OP
             、
             D ynamic Proxies              、          :略策
                                   D ynamic Byte Code Generation          J ava Code
         。
    Generation             、
                    U se of a Custon Class Loader 、     L anguage Extensions

    機理代過紹介例範式程的際實用使經已,中理代態動與理代態靜前之在
    。 面 介 的 何 任 理 代 於 用 可,成 完 來 理 代 態 動 過 透 是 要 主 的
        S pring      AOP                                 ,制
    留 遺 些 一 是 像,別 類 理 代 以 用,理 代
                  S pring               用使以可也
                                       CGLIB        ,面 方 一 另
             L egacy classes                。)         (別類
    Weave

    Advice  在,)       (合 縫 為 之 稱 程 過 的 上 之 件 物 至 用 應 被   W eave         AOP   的合縫中
        (期 時 入 載 別 類、)            (期 時 譯 編:點 間 時 個 幾 有 式 方
                                       C ompile time                          C lassload
    time                        。)
                            R untime       (期時行執、)
    的體具詞名關相 的過紹介上以將,例實的
           DynamicProxyDemo                            合結         AOP
               :識認與解理的詞名個一每對於助有,示表來片圖用使




4 14
Chapter 4 Spring AOP




                              圖   4.6 AOP   意示詞名個各的

4.1.3 Spring AOP
 在別差的要主,式方作實同不的念概 對其有會架框 的同不
              AOP                    AOP
)     (合縫被何如們它及以,度程富豐的
              Pointcuts A spects    、     的供提所於                            W eave
         。 等 式 方 的 理代 、 ) 式 方 義 定 的
                      Pointcuts       是像(式程用應至
     的定特用使不而,寫撰來言語式程 用是
    Spring        Advices         Java  的                                       AOP
 的 寫 撰,        或案檔態組 用使以可時
                  Pointcuts             義 定 在, 言 語
                                            XML              Annotation
 用以可就,法語的定特習學必不您,悉熟很都說來員人發開 於對式方
           Java
       Java  。          用運來式格 與言語式程 的悉熟
                              XML                 Spring AOP

     作實會 的 ,          API   現實來式方的 作實以擇選若   Advices Spring      AOP             AOP
 的範規所)
Alliance   h ttp://www.sourceforge.net/ projects/aopalliance
                                          (
 這,)          (畫計合聯的成組所體團多許由是
      A OP Alliance                          ,面 介              J oint project
     對是的目,範規面介的來出訂制循遵須必求要作實的 於對體團些
              AOP                                                               Java




                                                                                 4 1
4 16
                  。 理原的 作 運 後 背 其 解 理 易 容 會 , 時 式 方 定 設                           AOP
的新   Spring 2.0
            用使在,節細多許的                       Spring AOP
                                       握掌以可您是處好,式方
種 這是就 的 紹 介 要 先 首 , 時              Spring AOP
                                 紹 介 始 開一章 本 , 件 物 理 代 定 設
並,  Advice
         義定來          的中當AOP API           Spring
                                  作實須必您,式方的 現實                              AOP
本版前先或         Spring 1.2
                  是就也,式方的                      Spring API
                                         作實統傳是種一第
                  。式方的 現實種三了供提中        AOP            在             Spring 2.0
     。性裝封的件物壞破會                      Joinpoints
                               的員成 援支,為認中學哲計              Field
設的   Spring
          在為因是這,              Jointpoints
                             的員成 援支不                ,用應被Field         S pring
後前的行執法方在將                 Advices
                       是就也,            的法方援支只 Joinpoints                   Spring
                                    。用使來)                (          L egacy classes
別類舊是或別類)             T hird-party
                       (方三第的碼始原動更法無些一讓是上本基
式方個這且而,理代行進法無法方的 為告宣被於對以所,別類子生產              final
須 必 於 由,式 方 的        Proxy classes
                         用 使,低 降 度 合 耦 的 間 之 此 彼 件 組 的 式 程
用應 讓 以 可 這 , 先 優 為式方 的 面 介 作 實 以 該 應 您 , 中            在           Spring AOP
                   。)              P roxy classes
                                 ( 別 類 理代為 作 別 類 子 個 一 生 產
Targets為     CGLIB
               用使會             Spring
                           則 , 面 介 作 實 不果如 , 理 代 態 動 行 進 來
java.lang.reflect.Proxy
                  用使會期時行執在             則,面介的好義定先預作   Spring
實 Targets讓以可您,             Targets
                       至入導期時行執在是                的               Advices    Spring
                                                  。定設件物
理代的有所成完您為                 Spring
                      由,示 標 接 直 中 之 別 類 在,式 方 的                            Annotation
用使擇選以可也您。              入導 Advices           Targets
                                    為以可就,訊資關相義定中
檔定設在接直,面介何任作實不以可                     的您,中    Advices  在            Spring 2.0
                                              。性植移可的間
之式程用應         Java   的同不在別類作實              AOP
                                加增以,化準標面介作實 的                                   AOP
                     )   – http://openhome.cc           良信林(冊手術技           Spring 2.0
4 17
                                     。定設成完可即            Annotation
 的當適記標上      Advice 在要只,定設的瑣繁作中件文                 XML
                                               在用不是
 處 好,作 運 以 可 才 本 版 的 上 以   JDK 5.0
                                在須必式方種這以所,              Annotation
 到用使於由,援支             Annotation
                              的      @AspectJ
                                        用使是種三第
                               。面介的定特作實用不           且而Advice
 , 多許潔 簡 式 方 種 一 第 比 會上 定 設 在 , 籤 標   < aop>
                                       的新        Spring 2.0
                                                 用使並
 ,定設 的 XML   Schema                        XML
                   於基 用 使 須 必 您 , 定 設 的 於 基 是 種 二 第
 Chapter 4 Spring AOP
Spring 2.0   良信林(冊手術技               – http://openhome.cc         )

 4.2 Advices
 ,別類個一是就說來體具中 在,輯邏正真的
       Advices                了作 實
                         Aspect                     Java
 由。)      多許理管 中集來別類個一由(法 方個一為 計設的度粒細 更或                                Advices
 是像,      的同不種幾了供提
             Targets    ,同不機時的     至合縫於 S pring                         Advices
 小個這在 。
 Before Advice  、       、
                   A fter Advice、      A round Advice      T hrow Advice
        。        識認始開 來   用使、寫 撰從以可您, 中節
                                    Advices                Spring AOP



 4.2.1 Before Advice
 現實以可您,叫呼被前之行執法方的件物標目在會
       Before Advice
       作實來 面介
 org.springframework.aop.MethodBeforeAdvice                             Before Advice
                 :示所 下如義定 的面介該,輯 邏的
 package org.springframework.aop;

 public interface MethodBeforeAdvice extends BeforeAdvice {
     void before(Method method, Object[] args,
                   Object target) throws Throwable;
 }


 ,面 介           自承繼                   ,到看以可中義定在
                              M ethodBeforeAdvice                BeforeAdvice
   (面 介 籤 標 是 都 者 兩 後 , 面 介
    BeforeAdvice                 自承繼又面介 Advice          而                            T ag
 承繼
 interface           ,法方 何 任 義 定 無 而 示 標 作 用 是 只, )        M ethodBeforeAdvice
 執法方的定指所) (件物標目在會法方
    BeforeAdvice        b efore()           ,           了   T arget
      ,件物標目及數引、例實            的行執被得取以可您,行執被前之行 M ethod                             before()
 之畢完行執法方            在,果 結 的 何 任 回 傳 不 以 所 , 為 告 宣 上 法 方
                 void                                       before()
          。 行 執 被 會 就法方 的 上 件 物 標 目 則 否,外 例 出 丟 您 非 除 , 後
 的作實須必件物標目義定先首,                     用使 何 如 範 示 來 例 實 以
                                    Before Advice
                                                    :面介

4 18
Chapter 4 Spring AOP



  BeforeAdviceDemo                                           IHello.java
package onlyfun.caterpillar;

public interface IHello {
    public void hello(String name);
}



   個一義定著接           HelloSpeaker   現實其讓,別類      IHello   :面介
  BeforeAdviceDemo                                     HelloSpeaker.java
package onlyfun.caterpillar;

public class HelloSpeaker implements IHello {
    public void hello(String name) {
        System.out.println("Hello, " + name);
    }
}



, 下 況 情 的 改 修 何 任 行進它 對 不 在 , 畢 完 寫 撰 經 已
          HelloSpeaker                    在現
到拿您是這下一像想,息訊些一錄記以可,前之行執法方
          hello()                         在要想您
作實以可您。務服的誌日些一加增它對想但,碼始原有沒您,件組個一的
MethodBeforeAdvice             :如例,面介
  BeforeAdviceDemo                               LogBeforeAdvice.java
package onlyfun.caterpillar;

import   java.lang.reflect.Method;
import   java.util.logging.Level;
import   java.util.logging.Logger;
import   org.springframework.aop.MethodBeforeAdvice;

public class LogBeforeAdvice
        implements MethodBeforeAdvice {
    private Logger logger =
            Logger.getLogger(this.getClass().getName());




                                                                     4 1
Spring 2.0     良信林(冊手術技         – http://openhome.cc   )

           public void before(Method method, Object[] args,
                            Object target) throws Throwable {
               logger.log(Level.INFO,
                       "method starts..." + method);
       }
  }



  ,碼式程的訊資錄記些一了入加您,中作實的法方
              before()                     在
  的要需給務服供提以可,務服的立獨個一為計設被別類
  LogBeforeAdvice
                 : 義 定 下 如 中 檔義定 在 要 只 著 接 , 件 物
      BeforeAdviceDemo                                    beans-config.xml
  <?xml version="1.0" encoding="UTF-8"?>
  <beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">

           <bean id="logBeforeAdvice"
                 class="onlyfun.caterpillar.LogBeforeAdvice"/>

           <bean id="helloSpeaker"
                 class="onlyfun.caterpillar.HelloSpeaker"/>

           <bean id="helloProxy"
              class="org.springframework.aop.framework.ProxyFactoryBean">
               <property name="proxyInterfaces"
                          value="onlyfun.caterpillar.IHello"/>
               <property name="target" ref="helloSpeaker"/>
               <property name="interceptorNames">
                   <list>
                       <value>logBeforeAdvice</value>
                   </list>
               </property>
           </bean>

  </beans>




4 2
Chapter 4 Spring AOP



了用使還您,外之例實件物的                及
                          Advice     立建了除到意注
                                     Target
會別類個這,
org.springframework.aop.framework.ProxyFactoryBean
前 下一憶 回 ( 件 物 理 代 立 建 來 用
   BeanFactory                       是或
                      ApplicationContext             被
物理代立建要需而因,現實來制機理代過透是要主
           S pring AOP                        ,節小個一
在,面介的用運可時理代定設上性屬 "proxyInterfaces"         在要您,)件
,例實
"target"    定設上  Target       在,件物        定設上
                                   "interceptorNames"         Advice
定 有 所 上 面 介 至)     (合 縫 被 會         ,時 法 方 標 目 定 指 不 在
                          B efore Advice          W eave
                                         。前之法方的義
            :作運的            下 一 試測式 程 的 下 以 寫 撰 以 可
                                      Before Advice


  BeforeAdviceDemo                                      SpringAOPDemo.java
package onlyfun.caterpillar;

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

public class SpringAOPDemo {
    public static void main(String[] args) {
        ApplicationContext context =
                new ClassPathXmlApplicationContext(
                        "beans-config.xml");
        IHello helloProxy =
            (IHello) context.getBean("helloProxy");
        helloProxy.hello("Justin");
    }
}



為 面 介 作 操 換 轉 須 必,時 件 物 理 代 的 回 取 作 操 在 得 記                 IHello   來,面 介
                     : 果 結行執 的 式 程 個 這 下 一 看



                                                                        4 21
Spring 2.0   良信林(冊手術技              – http://openhome.cc       )




                       圖   4.4 BeforeAdviceDemo   果結行執的案專
               與           的計設所您,到看以可中例範個這在    HelloSpeaker        LogBeforeAdvice
               道知用不它,說來                 於對,件物的立獨個兩是
                              HelloSpeaker                       LogBeforeAdvice
      在寫撰 的關相                        與 何任有 沒 是 就 也 ( 在 存 的
                                    LogBeforeAdvice            API              Hello-
     ,上之件物的它其至用運以可也
 Speaker              LogBeforeAdvice       而,)中                                H ello-
 Speaker      。 計 設 的用 使 複 重 以 可 是 都
              LogBeforeAdvice                    與
 的用 使 複 重 可 計 設 , 識 辨 的
                  AOP         於重著,神精的          出看以可
                                           Aspects
 Advices。 件 物 的 用 使 複 重可計 設 , 識 辨 的 件 物 視 重 如 就 ,
                  OOP




         將一逐是您果如             .jar   將得記,話的中之理管案專至入加案檔
         spring-core.jar s pring-beans.jar s pring-context.jar spring-aop.jar
          、                               、       、
               與
           commons-logging.jar              。   入 加案 檔等
                                               Classpath




 4.2.2 After Advice
       After Advice        現 實 以 可 您,叫 呼 被 後 之 行 執 法 方 標 目 在 會         org.spring-
                      ,輯邏的
 framework.aop.AfterReturningAdvice作實來面介                    After Advice
 AfterReturningAdvice                      :下如義定的面介
 package org.springframework.aop;

 public interface AfterReturningAdvice extends Advice {
     void afterReturning(Object returnValue, Method m,



4 22
Chapter 4 Spring AOP



                 Object[] args, Object target) throws Throwable;
}


當        ,面介    自承繼接直
     AfterReturningAdvice                Advice        a fterReturning()
,件物標目與、數引、例實法方、值傳回的法方標目有數引的入傳中
例出丟,程流式程用應的來下接止中要若, 回傳法方
afterReturning()                void
                       。式方的一唯是外
方   的      為,中當子例的紹介中       在以可
               B efore Advice                     H elloSpeaker    hello()
       個一義定先首,         上加 , 後 之 行 執 法
                      AfterReturningAdvice                  LogAfterAdvice
              :面介           作實來別類
               AfterReturningAdvice


    AfterAdviceDemo                                   LogAfterAdvice.java
package onlyfun.caterpillar;

import     java.lang.reflect.Method;
import     java.util.logging.Level;
import     java.util.logging.Logger;
import     org.springframework.aop.AfterReturningAdvice;

public class LogAfterAdvice
                    implements AfterReturningAdvice {
    private Logger logger =
            Logger.getLogger(this.getClass().getName());

         public void afterReturning(Object object,
                                    Method method,
                                    Object[] args,
                                    Object target) throws Throwable {
             logger.log(Level.INFO, "method ends..." + method);
     }
}



     在要只著接          beans-config.xml   加增中   After Advice   在及以,例實的
的中
ProxyFactoryBean           "interceptorNames"   對加增         參的
                                                      LogAfterAdvice
:下 如 寫 撰 檔 義 定 , 考
                                                                         4 23
Spring 2.0   良信林(冊手術技        – http://openhome.cc     )

   AfterAdviceDemo                                     beans-config.xml
  <?xml version="1.0" encoding="UTF-8"?>
  <beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">

       <bean id="logBeforeAdvice"
             class="onlyfun.caterpillar.LogBeforeAdvice"/>

       <bean id="logAfterAdvice"
             class="onlyfun.caterpillar.LogAfterAdvice"/>

       <bean id="helloSpeaker"
             class="onlyfun.caterpillar.HelloSpeaker"/>

       <bean id="helloProxy"
          class="org.springframework.aop.framework.ProxyFactoryBean">
           <property name="proxyInterfaces"
                      value="onlyfun.caterpillar.IHello"/>
           <property name="target" ref="helloSpeaker"/>
           <property name="interceptorNames">
               <list>
                   <value>logBeforeAdvice</value>
                   <value>logAfterAdvice</value>
               </list>
           </property>
       </bean>

  </beans>



       的定設前之了除,中義定在                  LogBeforeAdvice   了入加還,外之
 與式程的它其,務服誌日的
 LogAfterAdvice                                        相案專
                                              BeforeAdviceDemo
    : 示 所 下 如 面 畫考參 個 一 的 時 行 執 , 同



4 24
Chapter 4 Spring AOP




                        圖   4.5 AfterAdviceDemo   果結行執的案專


            個一計設以可也您           LogAspect        現實時同它讓,別類       Method-
             與
         BeforeAdvice                       了為例範的節本,面介
                             AfterReturningAdvice
         將而因,作實的面介調強                Advice          。計設開分

4.2.3 Around Advice
標目在何如道知經已您,中紹介的
         Before Advice               與
                               After Advice        在
法 方在要 您 果 如 上 實 事 , 輯 邏 務 服 的      入 介後、 前 行 執 法 方 的 件 物
                                  Advices
             作實過透接直以可您,輯邏務服的
                Advices                      入加後前行執           org.aopalliance.
,務服 的 關 相 行 執 後 、 前行 執 法 方 於 , 面 介
intercept.MethodInterceptor
的面介                ,
                  Before Advice 與          供提別分用不而
                                       After Advice M ethodInterceptor
                                               :下如義定
package org.aopalliance.intercept;

public interface MethodInterceptor {
    public Object invoke(
        MethodInvocation methodInvocation) throws Throwable;
}


       是稱名件套的         到意注
             MethodInterceptor                      org.aopalliance.intercept   ,
作實示表這,訂制所        由是面介個這知得以可  AOP Alliance                         MethodInter-
的範規
ceptor    守遵於容相以可將,別類的面介                      AOP Alliance         AOP   。架框
                                                                            4 2
Spring 2.0   良信林(冊手術技           – http://openhome.cc        )

           在,是的同不
           Before Advice及             與
                             After Advice                   MethodInterceptor    的
 invoke()     用使否是定決行自要您,中法方                      org.aopalliance.intercept.
 會    。法方的件物標目行執來法方
 MethodInvocation         的proceed()                                p roceed()
 會機有您,前之束結     在以所,果結行執
                     Object 的後行執法方傳回             invoke()
 正真在有只,的然當,件物的干相不全完個一另傳回是或,件物個這改修
                        。做麼 這 會 才 候 時 的 要 必
       的前之在接直以可,        作 實何 如看 看來 際 實
                             MethodInterceptor                      AfterAdvice-
 Demo                     :寫 撰行 進 案 專
   AroundAdviceDemo                                     LogInterceptor.java
  package onlyfun.caterpillar;

  import   java.util.logging.Level;
  import   java.util.logging.Logger;
  import   org.aopalliance.intercept.MethodInterceptor;
  import   org.aopalliance.intercept.MethodInvocation;

  public class LogInterceptor implements MethodInterceptor {
      private Logger logger =
              Logger.getLogger(this.getClass().getName());

       public Object invoke(MethodInvocation methodInvocation)
                                               throws Throwable {
            logger.log(Level.INFO,
               "method starts..." + methodInvocation.getMethod());

            Object result = null;

            try {
              result = methodInvocation.proceed();
            }
            finally {
                logger.log(Level.INFO,
                   "method ends..." +
                   methodInvocation.getMethod() + "n");
            }



4 26
Chapter 4 Spring AOP




             return result;
      }
}



      個這用以可         Interceptor 的中案專        代取來
                                          AfterAdviceDemo         LogBefore-
Advice   與    LogAfterAdvice   :示所下如式方寫撰的檔義定 ,
                                  B ean


    AroundAdviceDemo                                        beans-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
  http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">

          <bean id="logInterceptor"
                class="onlyfun.caterpillar.LogInterceptor"/>

          <bean id="helloSpeaker"
                class="onlyfun.caterpillar.HelloSpeaker"/>

          <bean id="helloProxy"
              class="org.springframework.aop.framework.ProxyFactoryBean">
              <property name="proxyInterfaces"
                         value="onlyfun.caterpillar.IHello"/>
              <property name="target" ref="helloSpeaker"/>
              <property name="interceptorNames">
                  <list>
                      <value>logInterceptor</value>
                  </list>
              </property>
          </bean>

</beans>



      與果結行執         AfterAdviceDemo       圖考參以可,的樣一是果結行執的案專
4.5    。面畫的

                                                                        4 27
Spring 2.0     良信林(冊手術技             – http://openhome.cc      )

       Spring               入插先會,前法方個某行執正真在              Interceptor   個多有果如,
 Interceptor         行執後然,理處的己自行執會
                      I nterceptor                   個每,            M ethodInvocation
 的          個一下有沒果如,
     proceed()                個一下給轉程流行執將這,法方          Interceptor
 Interceptor回返層一層一再,後畢完行執法方,法方的叫呼正真行執就,
 Interceptor      。 程 流 的 身 本式程 用 應 回 返 疊 堆 開 離 後 最 , 疊 堆
 4.2.4 Throw Advice
     用使以可您,事些某作件物務服些某知通時生發外例在要想若                                             Throws
 Advice   作實須必, Spring        作實要想中         在,
                                      Throws Advice                 org.springframe-
 它,法方的何任義定有沒並面介個這而然,面介
 work.aop.ThrowsAdvice
 方       義 定 中 當 在 以 可 您 ,)         (面 介 籤 標 個 一 是 只
                          T ag interface                            afterThrowing
                            : 式 形 的下以 是 它 要 只 , 稱 名 法
 afterThrowing([Method], [args], [target], subclassOfThrowable);


 略省以可是示表等      與 、
                 []         如例,定設的中 號括方Method   a rgs     target
 是須必數參個這是就也,                      是的要定一中法方,的
                                subclassOfThrowable
 中
 Throwable的 定 設 所驗檢 會 , 時 生 發 外 例 在 , 別 類 子 的                      Throws Advice
 法方個兩是下以,行執它知通就話的有果如,法方的型類外例合符有否是
                                           :子例的告宣
 void afterThrowing(Throwable throwable);
 void afterThrowing(Method method, Object[] args,
                            Object target, Throwable throwable);


 不的型類生發外例依則,態型      的同不告宣果如上法方在        Throwable
        有告宣知通會       如例,法方的同不知通會,同   SomeException                    SomeException
  。法方的       有告宣知通會        而,法方的數參
                      OtherException                    OtherException




4 28
Chapter 4 Spring AOP



您,法 方 的 應 對 行 執 是 只 務 任 的            ,時 生 發 外 例 當 到 意 注
                          T hrow Advice
,後畢完行執   Throws Advice在,掉理處外例將中                     在能不並
                                             Throw Advice
的式 程 用 應 入 介 不 並           ,中之式程用應至播傳被仍外例的先原
                                    T hrow Advice
     在要 想 果 如 , 的 責 負要所 身 本 式 程 用 應 是 舊仍理 處 外 例 , 理 處 外 例        Throw
    。 外 例 的 它 其 出 丟 是法作 , 程 流 理 處 的 式 程 用 應 止 中 時 理 處
Advice

      :面介         義定 先 首 , 子 例 際 實 的
          Throws Advice                           個看來
                                                 IHello


  ThrowAdviceDemo                                           IHello.java
package onlyfun.caterpillar;

public interface IHello {
    public void hello(String name) throws Throwable;
}



作實來別類              個一義定著接
                 HelloSpeaker               IHello   在並,面介    hello()   方
 : 出 丟 外 例 的 時 誤錯生 發 式 程 擬 模 中 當 法
  ThrowAdviceDemo                                     HelloSpeaker.java
package onlyfun.caterpillar;

public class HelloSpeaker implements IHello {
    public void hello(String name) throws Throwable {
        System.out.println("Hello, " + name);
        //    外例生發!誤錯式程!歉抱     XD
        throw new Exception("
           外例生發                     ...");
    }
}



入 介 , 時 外 例 出 丟式程 用 應 在 要 需 您 果 如                       服些一供提
                                              Throw Advice
   作 實 以 可 則 , 訊 資外例 些 一 錄 記 如 例 , 務      ThrowAdvice        :面介


                                                                        4 2
Spring 2.0   良信林(冊手術技        – http://openhome.cc     )

      ThrowAdviceDemo                                SomeThrowAdvice.java
  package onlyfun.caterpillar;

  import   java.lang.reflect.Method;
  import   java.util.logging.Level;
  import   java.util.logging.Logger;
  import   org.springframework.aop.ThrowsAdvice;

  public class SomeThrowAdvice implements ThrowsAdvice {
      private Logger logger =
              Logger.getLogger(this.getClass().getName());
      public void afterThrowing(Method method, Object[] args,
                                 Object target, Throwable subclass) {
          //   外例錄記
          logger.log(Level.INFO,
                  "Logging that a " + subclass +
                  "Exception was thrown in " + method);

       }
  }



  讓,義定的下以下寫中檔義定 在著接
               Bean                                Throw Advice   生發外例在
               :務服誌日供提時
      ThrowAdviceDemo                                    beans-config.xml
  <?xml version="1.0" encoding="UTF-8"?>
  <beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">

       <bean id="someThrowAdvice"
             class="onlyfun.caterpillar.SomeThrowAdvice"/>

       <bean id="helloSpeaker"
             class="onlyfun.caterpillar.HelloSpeaker"/>

       <bean id="helloProxy"




4 3
Chapter 4 Spring AOP



          class="org.springframework.aop.framework.ProxyFactoryBean">
         <property name="proxyInterfaces"
                    value="onlyfun.caterpillar.IHello"/>
         <property name="target" ref="helloSpeaker"/>
         <property name="interceptorNames">
             <list>
                 <value>someThrowAdvice</value>
             </list>
         </property>
     </bean>

</beans>



     下 一 試 測來式 程 的 下 以 寫 撰 以 可       Throw Advice   :作運般期預如否是
    ThrowAdviceDemo                                 SpringAOPDemo.java
package onlyfun.caterpillar;

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

public class SpringAOPDemo {
    public static void main(String[] args) {
        ApplicationContext context =
                new ClassPathXmlApplicationContext(
                        "beans-config.xml");
        IHello helloProxy =
            (IHello) context.getBean("helloProxy");

           try {
               helloProxy.hello("Justin");
           }
           catch(Throwable throwable) {
               // 理處外例的式程用應
               System.err.println(throwable);
           }
     }
}




                                                                  4 31
4 32
              果結行執的案專       4.6 ThrowAdviceDemo   圖
                                :面畫 考 參 的 時 行 執 個 一
看看來,務服誌日的外額供提              T hrow Advice
                            ,輯 邏 的 外 例 理 處 式 程 用 應 入
介不 T hrow Advice
        ,輯 邏 的 理 處 外 例 了 義 定 身 本 式 程 用 應,中 式 程 在
              )    – http://openhome.cc    良信林(冊手術技   Spring 2.0
Chapter 4 Spring AOP




4.3 Pointcut、Advisor
行執面介的理代至合縫接直是都    的義定所,中節小個一前在         Advice
的部細更義定以可還上實事,時生發外例中程過法方行執在者或,後、前
在。)機時用應的    (   的趣興感了義定
             P ointcut     。機時合縫            Jointpoint   A dvice
,    合結體具,例實
Spring         供提        用使,中
                   PointcutAdvisor            Pointcut                  Advice
Spring    。      的應對有都
                Pointcut  的建內              PointcutAdvisor



4.3.1 NameMatchMethodPointcutAdvisor
  了義定
    Pointcut             Jointpoint   在,   Spring   用使中    PointcutAdvisor   供提來
,   合結、
Pointcut          Advice      P ointcutAdvisor        為
                                                     Advisor   ,面介子的     A dvisor
  :下如義定的於面介
package org.springframework.aop;

import org.aopalliance.aop.Advice;

public interface Advisor {
    boolean isPerInstance();
    Advice getAdvice();
}


    PointcutAdvisor       於面介     Spring   :下如義定的中
package org.springframework.aop;

public interface PointcutAdvisor extends Advisor {
    Pointcut getPointcut();
}


的建內中Spring                Pointcut的應對有都          PointcutAdvisor   介 來 先 邊 這 在,
 用使何如,下一紹                Spring     的供提所     org.springframework.aop.support.



                                                                              4 33
Spring 2.0   良信林(冊手術技          – http://openhome.cc        )

 用,       的本基最是這,
 NameMatchMethodPointcutAdvisor                            PointcutAdvisor
 定指)     (式示表用使可,例 實
           Spring             態靜中
                         Pointcut          供提以                e xpression
 表   如例,定指來 用是者或,稱名法方之上標目的用應要所
 Advice                                                *                hello*
 的定指用應會都,時稱名法方的頭開為作     hello 以上件物理代行執示
 。)法方的理代有所至用套被會
 Advices             ,子例的前之題主個這在(   A dvice

        :面介的    了 義 定 您 設 假,說 來 子 例 的 際 實 個 舉 IHello


      NameMatchDemo                                                IHello.java
  package onlyfun.caterpillar;

  public interface IHello {
      public void helloNewbie(String name);
      public void helloMaster(String name);
  }



       義定著接     HelloSpeaker   作實來別類      IHello   :面介
      NameMatchDemo                                         HelloSpeaker.java
  package onlyfun.caterpillar;

  public class HelloSpeaker implements IHello {
      public void helloNewbie(String name) {
          System.out.println("Hello, " + name + " newbie!");
      }

       public void helloMaster(String name) {
           System.out.println("Hello, " + name         + " master!");
       }
  }



        到用使會邊這如例,              的單簡 個 一 寫 撰 以 可 著 接
                                 Advice                          BeforeAdvice-
 Demo  考參請,限有幅篇於基,  LogBeforeAdvice       的中案專                       4.2.1   的中
        。 碼 式 程 出 列複重 再 不 邊 這 , 寫 撰 之 別 類
 LogBeforeAdvice


4 34
Chapter 4 Spring AOP



         用使,檔義定    的下以寫撰著接
                         Bean                 NameMatchMethodPointcut-
    :起一在合結
Advisor      將並,例實
              Pointcut 供提          Advice


  NameMatchDemo                                        beans-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
  http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">

    <bean id="logBeforeAdvice"
          class="onlyfun.caterpillar.LogBeforeAdvice"/>

    <bean id="helloAdvisor"
          class="org.springframework.aop.
                  → support.NameMatchMethodPointcutAdvisor">
       <property name="mappedName" value="*Newbie"/>
       <property name="advice" ref="logBeforeAdvice"/>
    </bean>

    <bean id="helloSpeaker"
          class="onlyfun.caterpillar.HelloSpeaker"/>

    <bean id="helloProxy"
       class="org.springframework.aop.framework.ProxyFactoryBean">
        <property name="proxyInterfaces"
                   value="onlyfun.caterpillar.IHello"/>
        <property name="target" ref="helloSpeaker"/>
        <property name="interceptorNames">
            <list>
                <value>helloAdvisor</value>
            </list>
        </property>
    </bean>

</beans>



 在    NameMatchMethodPointcutAdvisor        由,上性屬
                                              "mappedName"        的
了定指於       "*Newbie"   行 執 以 所,             合 符 稱 名 法 方 於 由,時 法 方
                                  helloNewbie()


                                                                     4 3
Spring 2.0   良信林(冊手術技         – http://openhome.cc     )

 程的下以寫撰以可,輯邏務服的
 "*Newbie"                    用應會就,
                         " logBeforeAdvice"
               : 期 預 合 符 否 是 果結看 看 , 試 測 行 進 來 式
      NameMatchDemo                                    SpringAOPDemo.java
  package onlyfun.caterpillar;

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

  public class SpringAOPDemo {
      public static void main(String[] args) {
          ApplicationContext context =
                  new ClassPathXmlApplicationContext(
                          "beans-config.xml");

            IHello helloProxy =
                (IHello) context.getBean("helloProxy");

            helloProxy.helloNewbie("Justin");
            helloProxy.helloMaster("caterpillar");
       }
  }



       : 示 所 下 如 面 畫考參 果 結 個 一 的 時 行 執



                     圖   4.7 NameMatchDemo    果結行執的案專
       用使,時     義定在以可也您  Advisor                       個多行進性屬
                                              "mappedNames"
 Pointcut 改修可如例,義定式示表               beans-config.xml     :容內的下以為

4 36
Chapter 4 Spring AOP



<beans ...>
    ....
    <bean id="helloAdvisor"
          class="org.springframework.aop.
                    → support.NameMatchMethodPointcutAdvisor">
       <property name="mappedNames">
            <list>
                <value>helloNewbie</value>
                <value>helloMaster</value>
            </list>
       </property>
       <property name="advice" ref="logBeforeAdvice"/>
    </bean>

    ....
</beans>



4.3.2 RegExpMethodPointcutAdvisor
     Spring                 的供提
                       org.springframework.aop.support.RegexpMethod-
寫撰來
PointcutAdvisor     用使您讓以可       Regular expression          Pointcut   示表
  合符在,例實的     Spring  態靜中     供提以用,式
                             Pointcut                   Regular expression
  : 號 符 個幾的 下 以 用 使 以 可 您 ,
              Advices         用應下況情的
    4.1 RegExpMethodPointcutAdvisor
號符的用可時義定                           表
號符                          述描
.                     元字一單何任合符
+                 次多或次一元字個一前合符
*                 次多或次零元字個一前合符
                 Escape 何任   Regular expression   號符的到用使



                                                                        4 37
Spring 2.0      良信林(冊手術技          – http://openhome.cc   )

 的合 符 要 所 定 指 您 讓 性 屬        的
       RegexpMethodPointcutAdvisor          "pattern"
 合符求要若如例,稱名法方加)稱名件套括包(稱名別類整完
  :寫 撰 下 如 要 則 , 稱 名 法 方 的 始 開 的 下
 onlyfun.caterpillar.IHello         hello


 onlyfun.caterpillar.IHello.hello.*


 符 定指要中式示表以所,用使
             .                           被經已號符 於由
                             Regular expression                       .
 名 法方對 針 算 打 只 果 如 , 式 方 的 用 使 是 就 也 , )
                   E scape                    (脫跳要則,號
                                             .
                       :寫 撰 麼 這 以 可 則 , 稱名件 套 管 不 而 , 對 比 稱
 .*hello.*


 與別 類 的 用 使 所 中 案 專        用使以可
                  NameMatchDemo                           Advice一改要只,
    Bean          :如例,了以可就檔義定 下
   RegexpMatchDemo                                        beans-config.xml
  <?xml version="1.0" encoding="UTF-8"?>
  <beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">

       <bean id="logBeforeAdvice"
             class="onlyfun.caterpillar.LogBeforeAdvice"/>

       <bean id="regExpAdvisor"
             class="org.springframework.aop.
                 → support.RegexpMethodPointcutAdvisor">
          <property name="pattern" value=".*Newbie"/>
          <property name="advice" ref="logBeforeAdvice"/>
       </bean>

       <bean id="helloSpeaker"
             class="onlyfun.caterpillar.HelloSpeaker"/>

       <bean id="helloProxy"



4 38
Chapter 4 Spring AOP



       class="org.springframework.aop.framework.ProxyFactoryBean">
         <property name="proxyInterfaces"
                    value="onlyfun.caterpillar.IHello"/>
         <property name="target" ref="helloSpeaker"/>
         <property name="interceptorNames">
             <list>
                 <value>regExpAdvisor</value>
             </list>
         </property>
    </bean>
</beans>



    用應要法方的尾結          為稱名法方合符定設,中義定的面上在        Newbie
Advice    與 果 結 行 執 以 所 , 稱 名 別 類 、 件 套 的 面 前 其 論 無 且,         NameMatch-
Demo                            。的樣一是果結行執的案專
4.3.3 ControlFlowPointcut
所 是 org.springframework.aop.support.ControlFlowPointcut           Sping
,中法方某的別類定指個某,中疊堆行執的法方在斷判為用作,別類的供提
定確會才期時行執在是這於由,作動個某行執件物標目的您求要經曾否是
       。能功Advices     態動的供提 是以所,
                            Spring  入介否是       Pointcut


為別類                 的中               以
         NameMatchMethodPointcutAdvisor          LogBeforeAdvice
要中法 方 個 某 在 否 是 , 中 別 類         在道知要想您,例
                    onlyfun.caterpillar.Some
        入介則,話的有果如,作動些某行執件物標目的定指過求                               LogBefore-
Advice      :寫撰下如檔義定 將以可,務服誌日供提來  Bean


  ControlFlowDemo                                         beans-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/beans




                                                                          4 3
Spring 2.0   良信林(冊手術技           – http://openhome.cc   )

      http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">

       <bean id="some" class="onlyfun.caterpillar.Some"/>

       <bean id="logBeforeAdvice"
             class="onlyfun.caterpillar.LogBeforeAdvice"/>

       <bean id="helloFlowControlPointcut"
          class="org.springframework.aop.support.ControlFlowPointcut">
           <constructor-arg value="onlyfun.caterpillar.Some"/>
       </bean>

       <bean id="helloAdvisor"
        class="org.springframework.aop.support.DefaultPointcutAdvisor">
           <property name="advice" ref="logBeforeAdvice"/>
           <property name="pointcut" ref="helloFlowControlPointcut"/>
       </bean>

       <bean id="helloSpeaker"
             class="onlyfun.caterpillar.HelloSpeaker"/>

       <bean id="helloProxy"
          class="org.springframework.aop.framework.ProxyFactoryBean">
           <property name="proxyInterfaces"
                      value="onlyfun.caterpillar.IHello"/>
           <property name="target" ref="helloSpeaker"/>
           <property name="interceptorNames">
               <list>
                   <value>helloAdvisor</value>
               </list>
           </property>
       </bean>

  </beans>



  ,別類         了定指,時構建        在
           ControlFlowPointcut               onlyfun.caterpillar.Some
  是就也(件物標目的定指了求要法方個某的中別類
               Some        在若示表
      (      用應則,作動些某行執)例實
  "helloSpeaker"                               Before Advice    l ogBefore-
  Advice   :寫撰下如別類 ,務服的誌日供提)     S ome



4 4
Chapter 4 Spring AOP



    ControlFlowDemo                                            Some.java
package onlyfun.caterpillar;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

public class Some implements ApplicationContextAware {
    private IHello helloProxy;

      public void setApplicationContext(
              ApplicationContext context) throws BeansException {
          helloProxy = (IHello) context.getBean("helloProxy");
      }

      public void helloEverybody() {
          helloProxy.helloNewbie("Justin");
          helloProxy.helloMaster("caterpillar");
      }

      public void hello() {
          System.out.println("Hello!");
      }
}



             得取便方了為ApplicationContext   得 獲以   helloSpeaker   ,件物理代的
Some         了現實別類 org.springframework.context.ApplicationContextAware
下一試測來式程的單簡個一寫撰以可著接,面介                           ControlFlowPointcut   運的
              :示所下如,作
    ControlFlowDemo                                  SpringAOPDemo.java
package onlyfun.caterpillar;

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

public class SpringAOPDemo {



                                                                      4 41
Spring 2.0   良信林(冊手術技          – http://openhome.cc           )

       public static void main(String[] args) {
           ApplicationContext context =
                   new ClassPathXmlApplicationContext(
                           "beans-config.xml");

           Some some = (Some) context.getBean("some");

           if(args.length > 0 && "run".equals(args[0])) {
               some.helloEverybody();
           }
           else {
               some.hello();
           }
       }
  }



                                    與都, 式 程 的 出 列 未 餘 其
                                NameMatchDemo            邊 這, 同 相 式 程 的 中 案 專
                             考參以可容內式程的整完,出列再不就           下一看來,案專
                                              ControlFlowDemo
                                                。果結的行執
 訊字文的           現 出會 只 則 , 數 引      供提 有 沒 時 式 程 行 執 果 如
                                    "run"                       "Hello!"
 不並中疊堆行執在,               Some  的例實 行執有沒為因是這,息
                                            helloEverybody()
 某行執例實               求要曾法方某的別類 :義定的定指所合符
                       S ome                          " helloSpeaker"
                                                    。作動些
 的別類          行執會則,數引              了供提時式程行執果如
                                      "run"                        Some
 行執件物理代的
 helloEverybody()           求要中法方,法方           "helloSpeaker"
 因, 容 內 的 定 指 中 檔 義 定 合 符 , 法 方
 helloNewbie()      helloMaster()             與   Bean
 :示所 下 如 果 結 的 行 執 個一 , 息 訊 務 服 供 提 來
           LogBeforeAdvice                          用應會而




4 42
4 43
                        數引的時行執定指中            Eclipse   在   4.9   圖
                   :如例,數引入輸中框字文」                                       arguments
       P rogram
           「在,籤 頁」              A rguments
                       「擇 選 後 然,令 指」                                 R un/Run...   「
       的上單選           Eclipse
                 行執以可,數引的時行執定指要中                                       Eclipse     在
    。      Pointcut
              態 靜 用 使 量儘, 下 況 情 的 能 可 在 議建此 因 , 遲 延 能 效 的 倍
 10    5                  JDK
  到 有 會 能 可 上 的同不 在 , 慢 很 會 時 行 執以所 , 行 進 期 時 行 執 在
 是斷 判 的 疊 堆 行 執 於 由,出 付 的 上 能 效 於 在 是 就 題 問 的       態動                Pointcut
                       果結行執的案專       4.8 ControlFlowDemo         圖
 Chapter 4 Spring AOP
Spring 2.0     良信林(冊手術技            – http://openhome.cc    )

 4.3.4 Pointcut 介面

        的
       Spring      Pointcut   作實過透是      org.springframework.aop.Pointcut   面介
 :下 如 義 定 其 , 現 實 來
 package org.springframework.aop;

 public interface Pointcut {
     ClassFilter getClassFilter();
     MethodMatcher getMethodMatcher();
     Pointcut TRUE = TruePointcut.INSTANCE;
 }


       Pointcut.TRUE 是     的回傳它,作實單簡的面介
                              Pointcut      是                    ClassFilter
 ClassFilter.TRUE    。         回傳 是       的回傳而,
                                  MethodMatcher        MethodMatcher.TRUE

       ClassFilter   :示所下如義定其,    用應要否是別類個一定決面介    Advice


 package org.springframework.aop;

 public interface ClassFilter {
     boolean matches(Class clazz);
     ClassFilter TRUE = TrueClassFilter.INSTANCE;
 }


       matches() ,義定的           合符是不是別類的入傳定決要中法方            Pointcut
 ClassFilter.TRUE總法方          的它,作實單簡的面介
                         ClassFilter             是            matches()
  回傳是     true   這 用使以 可 則 , 稱 名 法 方 到 慮 考 只
                                     Pointcut的立建要想果如,
 。法方個
  而      MethodMatcher        用應要否是法方個某 定決           Advice :示所下如義定其,
 package org.springframework.aop;

 import java.lang.reflect.Method;



4 44
Chapter 4 Spring AOP




public interface MethodMatcher {
    boolean matches(Method method, Class targetClass);
    boolean isRuntime();
    boolean matches(Method method,
                       Class targetClass, Object[] args);
    MethodMatcher TRUE = TrueMethodMatcher.INSTANCE;
}


    matches()   合符否 是 法 方 個 某 的 別 類 個 某 定 決 法 方                Pointcut   兩有,義定
                     是像,        態 靜 於 用使本 版 個 一 第 , 本 版 個
                                     Pointcut             NameMatchMethodPoint-
, 行執被 會 是 總 法 方 個 一 第 ,
cutAdvisor   R egExpMethodPointcutAdvisor       、
       個二第時此, 回傳會
             Pointcut                  則,
                             isRuntime()         態靜是果如 false               matches()
       的本版個二第,時 為                     在有只 , 行 執 被 會 不 法 方
                             isRuntime()        true                       matches()
                        。
                     ControlFlowPointcut    如例,行執被會才
版個 一 第 的 它 , 作 實 單 簡 的
    MethodMatcher.TRUE             是
                                 MethodMatcher
態靜示表, 回傳是總
     matches()                 , 回傳是總
                              true   i sRuntime()    的本          false
出丟會就則否,法方
Pointcut                 的本版個二第行執以可不以所,          matches()
                          。外例
UnsupportedOperationException



4.3.5 Pointcut 交集、聯集操作

    個幾有現發您,中之這在且並,     個多了立建果如
                         Pointcuts                                          Pointcuts
現對接直以可您,時義定的    個一另為成,起一在合組以可義定的           Pointcuts
,作操的) (集聯、)
     Pointcuts   (集交行進,件物            的在
                                     I ntersection              U nion
的    是
org.springframework.aop.support.ComposablePointcut                        Pointcut
:作操個這成完來法方   、       的它作 操 以 可 , 別 類 作 實
                             intersection()      u nion()


ComposablePointcut      intersection(ClassFilter filter);
ComposablePointcut      intersection(MethodMatcher mm)
ComposablePointcut      intersection(Pointcut other)
ComposablePointcut      union(ClassFilter filter)


                                                                                     4 4
Spring 2.0   良信林(冊手術技          – http://openhome.cc   )

 ComposablePointcut union(MethodMatcher mm)


       :如例
 Pointcut pc = new ComposablePointcut()
                      .union(classFilter)
                      .intersection(methodMatcher)
                      .intersection(pointcut);


 在        ComposablePointcut   個兩理 處 以 可 法 方 有 沒 中    Pointcut  您,集聯的
 用使要                           的
          org.springframework.aop.support.Pointcuts   union()   :如 例,法方
 Pointcut union = Pointcuts.union(pointcut1, pointcut2);


 如,作操集聯或集交行進以可才寫撰接直中式程在須必是這,的然當
    於 後 然 , 別 類 個 一 計設以 可 則 , 告 宣 接 直 中 檔 義 定 在 望 希 您 果
              Bean                                                  Bean
 :如 例 , 性 用 重 的 作 操      加 增 以 可 這 , 例 實的別 類 該 告 宣 中 檔 義 定
                                           Pointcut


 package onlyfun.caterpillar;

 import java.util.List;

 import org.springframework.aop.ClassFilter;
 import org.springframework.aop.MethodMatcher;
 import org.springframework.aop.Pointcut;
 import org.springframework.aop.
                         framework.AopConfigException;
 import org.springframework.aop.support.Pointcuts;

 public class UnionPoint implements Pointcut {
     private Pointcut pointcut;

       public ClassFilter getClassFilter() {
           return getPointcut().getClassFilter();
       }

       public MethodMatcher getMethodMatcher() {
           return getPointcut().getMethodMatcher();


4 46
Chapter 4 Spring AOP



    }

    public void setPointcuts(List pointcuts) {
        if(pointcuts == null || pointcuts.size == 0) {
            throw new AopConfigException(
                          "個一定設要少至     Pointcut");
        }

        pointcut = (Pointcut) pointcuts.get(0);

        for(int i = 0; i < pointcuts.size(); i++) {
             Pointcut next = (Pointcut) pointcuts.get(i);
             pointcut = Pointcuts.union(pointcut, next);
        }
    }

    private Pointcut getPointcut() {
        if(pointcut == null) {
              throw new AopConfigExeption("   定設有沒   Pointcut");
        }
          return pointcut;
    }
}




                                                                   4 47
4 48
                          。能功的常為以
      習很是則,說來)式函(法方的作操可加增件物為態動對,員
      人計設的       JavaScript
               悉熟如例,員人計設的言語本腳態動悉熟
         。    Introduction
                      現實來             framework.aop.IntroductionInterceptor
org.spring-作實過透以可,中                   Spring AOP
                                      在上實事,議思可不得顯
法方的作操可加增件物為態動,說來點觀的計設別類言語式程 就                                       Java
          。 上 之 件 物 到 法方作 操 的 外 額 些 一 加 增以可 卻 , 下 況 情 的 案 檔
別類之件物該改修不在,件物的好義定已個某讓如例,」) 法 方 的作 操 可
了加增是就說來體具(責職的件物標目了加增接直,義定為行的件物標目
了響影「它,看來度角的者用使從,                         Advice
                                     的別特個是                     Introduction
          。 作 動 的 誌 日 些一了 加 增 乎 似 來 看 法 方 些 某 讓 如 例 , 」 為 行 的
法 方 些 某 上 件 物 標 目 了 響 影「們 它 , 看 來 度 角 的 者 用 使 從 ,                 Throw Advice
、 A round Advice
               、      A fter Advice
                          、             Before Advice
                                          的過紹介前之於對
                                       4.4.1 IntroductionInterceptor
              。責職的有沒所先原) (入加態動                                 M ixin
件物為,為行的作操可些一了多空憑件物像好就,為行的件物個整入介接
直是而,務服入介後前法方在   等      、        Advice
                               像不           A fter Advice     BeforeAdvice
它,看來上為行從,   的殊特種一是     Advice
                        ,中   在                I ntroduction       Spring
                                                  4.4 Introduction
                  )   – http://openhome.cc        良信林(冊手術技              Spring 2.0
Chapter 4 Spring AOP



            與
    IntroductionInterceptor     承繼    MethodInterceptor       DynamicIntro-
      自承繼(法方
ductionAdvice                          中其,面介
                           implementsInterface()                   Dynamic-
                 的前目示表,話的 回傳果如)
IntroductionAdvice            true                     IntroductionInterceptor
用使要您時此,)面介的為行加增外額要是就也(面介的定規了作實
用使可不您,為行的外額行執件物標目讓,法方的上面介行執
invoke()
的有沒 來 原 上 件 物 是 的 行 執 要 為 因 , 法 方
MethodInvocation       proceed()          的
           proceed()        。義意有沒法方               行執,為行
假,說來子例的際實個舉,象抽較比會      Introduction       解理來上字文從
                                : 別 類 的 下以有 經 已 中 統 系 的 您 設
  IntroductionDemo                                               ISome.java
package onlyfun.caterpillar;

public interface ISome {
    public void doSome();
}



  IntroductionDemo                                                 Some.java
package onlyfun.caterpillar;

public class Some implements ISome {
    public void doSome() {
        System.out.println("   。。。責職的件物來原        ");
    }
}



的作 操 可 些 一 加 增 別 類    為 , 下 況 情 的 案檔始 原 改 修 不 在 望 希 您
                                              Some
也的道知一唯,案檔            有只 , 有 沒 都 案 檔 碼 始原連 至 甚 您 許 也 , 法 方
                                                .class
可別類       望 希 , 下 況 情的改 修 出 做 們 它 對 不 在 , 明 說 的 們 它 是 許
            API                                                 Some
       doOther()                       。法方          加增以

                                                                           4 4
Spring 2.0   良信林(冊手術技        – http://openhome.cc   )

        作實由藉以可,中
           Spring  在                IntroductionInterceptor   面上成完來面介
    :面介立建法方    為先首,務任的
                    doOther()


      IntroductionDemo                                         IOther.java
    package onlyfun.caterpillar;

    public interface IOther {
        public void doOther();
    }



        個一義定著接       OtherIntroduction   作實時同別類     IntroductionInterceptor
    :如例,面介   與面介
           IOther


      IntroductionDemo                            OtherIntroduction.java
    package onlyfun.caterpillar;

    import org.aopalliance.intercept.MethodInvocation;
    import org.springframework.aop.IntroductionInterceptor;

    public class OtherIntroduction
                  implements IntroductionInterceptor, IOther {
        // 自作實否是    IOther 面介
        public boolean implementsInterface(Class clazz) {
            return clazz.isAssignableFrom(IOther.class);
        }

        public Object invoke(MethodInvocation methodInvocation)
                                          throws Throwable {
            //   自來法方的行執果如    IOther 義定的面介
            if(implementsInterface(
                methodInvocation.getMethod().getDeclaringClass())) {
                //  (入加外額行執    mixin為行的)
                return methodInvocation.getMethod().
                        invoke(this, methodInvocation.getArguments());
            }
            else {
                return methodInvocation.proceed();



4
Chapter 4 Spring AOP



          }
      }

      public void doOther() {
          System.out.println("   。。。責職的加增       ");
      }
}



     在要著接     Bean   將中檔義定       Introduction   至合縫     Some   用 使, 上 之 件 物
org.springframework.aop.support.DefaultIntroductionAdvisor     以可就
:如例,了
    IntroductionDemo                                       beans-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
  http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">

      <bean id="some"
            class="onlyfun.caterpillar.Some"/>

      <bean id="otherIntroduction"
            class="onlyfun.caterpillar.OtherIntroduction"/>

      <bean id="otherAdvisor"
            class="org.springframework.aop.
                     → support.DefaultIntroductionAdvisor">
            <constructor-arg ref="otherIntroduction"/>
            <constructor-arg value="onlyfun.caterpillar.IOther"/>
      </bean>

      <bean id="proxyFactoryBean"
         class="org.springframework.aop.framework.ProxyFactoryBean">
          <property name="proxyInterfaces"
                    value="onlyfun.caterpillar.ISome"/>
          <property name="target" ref="some"/>
          <property name="interceptorNames">




                                                                         4    1
Spring 2.0   良信林(冊手術技         – http://openhome.cc   )

                  <list>
                      <value>otherAdvisor</value>
                  </list>
              </property>
          </bean>

    </beans>



                    它給要需,時構建在
         DefaultIntroductionAdvisor                   IntroductionInterceptor
    測式程的單簡個一寫撰來,在現,面介的為行外額理代要所及以,例實的
      :為 行 加 增 外 額 件 物 為謂何 解 了 步 一 進 更 以 可,中 當 式 程 個 這 從 , 試
        IntroductionDemo                                SpringAOPDemo.java
    package onlyfun.caterpillar;

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

    public class SpringAOPDemo {
        public static void main(String[] args) {
            ApplicationContext context =
                new ClassPathXmlApplicationContext(
                        "beans-config.xml");

               ISome some =
                   (ISome) context.getBean("proxyFactoryBean");

               some.doSome();

               //像好來看    some   責職了加增態動件物
               ((IOther) some).doOther();
          }
    }




4   2
Chapter 4 Spring AOP



      有會不並先原它,說來件物的考參所 於對
         some                                      doOther()操供可法方
    在現,制機     Spring AOP的           過透而然,作
                               Introduction          some   件物的考參所
: 果 結 的 行 執下一 看 來 以 可 , 作 操 以 可 法 方
     doOther()                          了多



                   圖   4.10 IntroductionDemo   果結行執的案專

4.4.2 DelegatingIntroductionInterceptor
    org.springframework.aop.support.DelegatingIntroductionInterceptor
可您, 別 類 作 實 的 供 提 所 面 介
  Spring AOP                            為中
                    IntroductionInterceptor           是
件物有帶以可並,為行的加增件物標目為望希加添,別類個這承繼接直以
        ,態狀的定鎖」否「、」是「有帶攜件物讓如例,態狀的己自                            D elegating-
                 。 節細的 份 部 大 了 作 實 經 已
IntroductionInterceptor

                :別類 的 樣 這 有 經 已 中 統系設 假 , 說 來 子 例 個 舉
  DelegatingIntroductionDemo                                   ISome.java
package onlyfun.caterpillar;

public interface ISome {
    public void setSome(String some);
    public String getSome();
}




                                                                        4     3
Spring 2.0    良信林(冊手術技        – http://openhome.cc           )


        DelegatingIntroductionDemo                                        Some.java
    package onlyfun.caterpillar;

    public class Some implements ISome {
        private String some;

          public void setSome(String some) {
              this.some = some;
          }

          public String getSome() {
              return some;
          }
    }



       個 一 加 增 以 可 望希您 , 下 況 情 的 容 內 式 程
                   Some.java                    改修不在                         locked
    定設來法方
        boolean    與     的作操可加增並,員成料資態型          lock()   的  unlock()
         定 鎖 則, 為 定 設 被
    locked         true   false   果 如, 或 為 員 成
                                       locked             true            setSome()
        。)          ( 動變可 不 為 定 鎖 件 物 將 是就也 , 行 執 被 法 無 法 方
                                                          I mmutable

    的件物標目至加添想是的義定面上,面介    ILockable       個一義定先以可
                                                  :法方作操
        DelegatingIntroductionDemo                                   ILockable.java
    package onlyfun.caterpillar;

    public interface ILockable {
        public void lock();
        public void unlock();
        public boolean isLocked();
    }



    承繼 著接          DelegatingIntroductionInterceptor   作實時同並,別類           ILockable
        :面介
4   4
Spring 2.0 技術手冊第四章 - Spring AOP
Spring 2.0 技術手冊第四章 - Spring AOP
Spring 2.0 技術手冊第四章 - Spring AOP
Spring 2.0 技術手冊第四章 - Spring AOP
Spring 2.0 技術手冊第四章 - Spring AOP
Spring 2.0 技術手冊第四章 - Spring AOP
Spring 2.0 技術手冊第四章 - Spring AOP
Spring 2.0 技術手冊第四章 - Spring AOP
Spring 2.0 技術手冊第四章 - Spring AOP
Spring 2.0 技術手冊第四章 - Spring AOP
Spring 2.0 技術手冊第四章 - Spring AOP
Spring 2.0 技術手冊第四章 - Spring AOP
Spring 2.0 技術手冊第四章 - Spring AOP
Spring 2.0 技術手冊第四章 - Spring AOP
Spring 2.0 技術手冊第四章 - Spring AOP
Spring 2.0 技術手冊第四章 - Spring AOP
Spring 2.0 技術手冊第四章 - Spring AOP
Spring 2.0 技術手冊第四章 - Spring AOP
Spring 2.0 技術手冊第四章 - Spring AOP
Spring 2.0 技術手冊第四章 - Spring AOP
Spring 2.0 技術手冊第四章 - Spring AOP
Spring 2.0 技術手冊第四章 - Spring AOP
Spring 2.0 技術手冊第四章 - Spring AOP
Spring 2.0 技術手冊第四章 - Spring AOP
Spring 2.0 技術手冊第四章 - Spring AOP
Spring 2.0 技術手冊第四章 - Spring AOP
Spring 2.0 技術手冊第四章 - Spring AOP
Spring 2.0 技術手冊第四章 - Spring AOP
Spring 2.0 技術手冊第四章 - Spring AOP
Spring 2.0 技術手冊第四章 - Spring AOP
Spring 2.0 技術手冊第四章 - Spring AOP
Spring 2.0 技術手冊第四章 - Spring AOP

More Related Content

What's hot

Ch13 整合 Spring MVC/Security
Ch13 整合 Spring MVC/SecurityCh13 整合 Spring MVC/Security
Ch13 整合 Spring MVC/Security
Justin Lin
 
【BS11】毎年訪れる .NET のメジャーバージョンアップに備えるために取り組めること
【BS11】毎年訪れる .NET のメジャーバージョンアップに備えるために取り組めること 【BS11】毎年訪れる .NET のメジャーバージョンアップに備えるために取り組めること
【BS11】毎年訪れる .NET のメジャーバージョンアップに備えるために取り組めること
日本マイクロソフト株式会社
 
Spring boot
Spring bootSpring boot
Spring boot
Pradeep Shanmugam
 
PUC SE Day 2019 - SpringBoot
PUC SE Day 2019 - SpringBootPUC SE Day 2019 - SpringBoot
PUC SE Day 2019 - SpringBoot
Josué Neis
 
Laravel の paginate は一体何をやっているのか
Laravel の paginate は一体何をやっているのかLaravel の paginate は一体何をやっているのか
Laravel の paginate は一体何をやっているのか
Shohei Okada
 
Springboot introduction
Springboot introductionSpringboot introduction
Springboot introduction
Sagar Verma
 
Ch9 .Best Practices for Class-Based Views
Ch9 .Best Practices  for  Class-Based ViewsCh9 .Best Practices  for  Class-Based Views
Ch9 .Best Practices for Class-Based Views
Willy Liu
 
Xke spring boot
Xke spring bootXke spring boot
Xke spring boot
sourabh aggarwal
 
Spring data jpa
Spring data jpaSpring data jpa
Spring data jpa
Jeevesh Pandey
 
【改訂版あり】クラウド・ネイティブ時代に最適なJavaベースのマイクロサービス・フレームワーク ~ Helidonの実力を見極めろ!
【改訂版あり】クラウド・ネイティブ時代に最適なJavaベースのマイクロサービス・フレームワーク ~ Helidonの実力を見極めろ!【改訂版あり】クラウド・ネイティブ時代に最適なJavaベースのマイクロサービス・フレームワーク ~ Helidonの実力を見極めろ!
【改訂版あり】クラウド・ネイティブ時代に最適なJavaベースのマイクロサービス・フレームワーク ~ Helidonの実力を見極めろ!
オラクルエンジニア通信
 
Spring - Part 1 - IoC, Di and Beans
Spring - Part 1 - IoC, Di and Beans Spring - Part 1 - IoC, Di and Beans
Spring - Part 1 - IoC, Di and Beans
Hitesh-Java
 
Spring Boot in Action
Spring Boot in Action Spring Boot in Action
Spring Boot in Action
Alex Movila
 
Spring boot
Spring bootSpring boot
Spring boot
Gyanendra Yadav
 
Spring Framework
Spring Framework  Spring Framework
Spring Framework
tola99
 
Ch03 請求與回應
Ch03 請求與回應Ch03 請求與回應
Ch03 請求與回應
Justin Lin
 
Maven基礎
Maven基礎Maven基礎
Maven基礎
Toshio Takiguchi
 
Spring framework in depth
Spring framework in depthSpring framework in depth
Spring framework in depth
Vinay Kumar
 
Conférence sur les annotations Java par Olivier Croisier (Zenika) au Paris JUG
Conférence sur les annotations Java par Olivier Croisier (Zenika) au Paris JUGConférence sur les annotations Java par Olivier Croisier (Zenika) au Paris JUG
Conférence sur les annotations Java par Olivier Croisier (Zenika) au Paris JUG
Zenika
 
サーバーサイドでの非同期処理で色々やったよ
サーバーサイドでの非同期処理で色々やったよサーバーサイドでの非同期処理で色々やったよ
サーバーサイドでの非同期処理で色々やったよ
koji lin
 
さくっと理解するSpring bootの仕組み
さくっと理解するSpring bootの仕組みさくっと理解するSpring bootの仕組み
さくっと理解するSpring bootの仕組み
Takeshi Ogawa
 

What's hot (20)

Ch13 整合 Spring MVC/Security
Ch13 整合 Spring MVC/SecurityCh13 整合 Spring MVC/Security
Ch13 整合 Spring MVC/Security
 
【BS11】毎年訪れる .NET のメジャーバージョンアップに備えるために取り組めること
【BS11】毎年訪れる .NET のメジャーバージョンアップに備えるために取り組めること 【BS11】毎年訪れる .NET のメジャーバージョンアップに備えるために取り組めること
【BS11】毎年訪れる .NET のメジャーバージョンアップに備えるために取り組めること
 
Spring boot
Spring bootSpring boot
Spring boot
 
PUC SE Day 2019 - SpringBoot
PUC SE Day 2019 - SpringBootPUC SE Day 2019 - SpringBoot
PUC SE Day 2019 - SpringBoot
 
Laravel の paginate は一体何をやっているのか
Laravel の paginate は一体何をやっているのかLaravel の paginate は一体何をやっているのか
Laravel の paginate は一体何をやっているのか
 
Springboot introduction
Springboot introductionSpringboot introduction
Springboot introduction
 
Ch9 .Best Practices for Class-Based Views
Ch9 .Best Practices  for  Class-Based ViewsCh9 .Best Practices  for  Class-Based Views
Ch9 .Best Practices for Class-Based Views
 
Xke spring boot
Xke spring bootXke spring boot
Xke spring boot
 
Spring data jpa
Spring data jpaSpring data jpa
Spring data jpa
 
【改訂版あり】クラウド・ネイティブ時代に最適なJavaベースのマイクロサービス・フレームワーク ~ Helidonの実力を見極めろ!
【改訂版あり】クラウド・ネイティブ時代に最適なJavaベースのマイクロサービス・フレームワーク ~ Helidonの実力を見極めろ!【改訂版あり】クラウド・ネイティブ時代に最適なJavaベースのマイクロサービス・フレームワーク ~ Helidonの実力を見極めろ!
【改訂版あり】クラウド・ネイティブ時代に最適なJavaベースのマイクロサービス・フレームワーク ~ Helidonの実力を見極めろ!
 
Spring - Part 1 - IoC, Di and Beans
Spring - Part 1 - IoC, Di and Beans Spring - Part 1 - IoC, Di and Beans
Spring - Part 1 - IoC, Di and Beans
 
Spring Boot in Action
Spring Boot in Action Spring Boot in Action
Spring Boot in Action
 
Spring boot
Spring bootSpring boot
Spring boot
 
Spring Framework
Spring Framework  Spring Framework
Spring Framework
 
Ch03 請求與回應
Ch03 請求與回應Ch03 請求與回應
Ch03 請求與回應
 
Maven基礎
Maven基礎Maven基礎
Maven基礎
 
Spring framework in depth
Spring framework in depthSpring framework in depth
Spring framework in depth
 
Conférence sur les annotations Java par Olivier Croisier (Zenika) au Paris JUG
Conférence sur les annotations Java par Olivier Croisier (Zenika) au Paris JUGConférence sur les annotations Java par Olivier Croisier (Zenika) au Paris JUG
Conférence sur les annotations Java par Olivier Croisier (Zenika) au Paris JUG
 
サーバーサイドでの非同期処理で色々やったよ
サーバーサイドでの非同期処理で色々やったよサーバーサイドでの非同期処理で色々やったよ
サーバーサイドでの非同期処理で色々やったよ
 
さくっと理解するSpring bootの仕組み
さくっと理解するSpring bootの仕組みさくっと理解するSpring bootの仕組み
さくっと理解するSpring bootの仕組み
 

Viewers also liked

Spring 2.0 技術手冊第十章 - 專案:線上書籤
Spring 2.0 技術手冊第十章 - 專案:線上書籤Spring 2.0 技術手冊第十章 - 專案:線上書籤
Spring 2.0 技術手冊第十章 - 專案:線上書籤
Justin Lin
 
Spring 2.0 技術手冊第九章 - API 封裝
Spring 2.0 技術手冊第九章 - API 封裝Spring 2.0 技術手冊第九章 - API 封裝
Spring 2.0 技術手冊第九章 - API 封裝
Justin Lin
 
Spring 2.0 技術手冊第八章 - View 層方案、Web 框架整合
Spring 2.0 技術手冊第八章 - View 層方案、Web 框架整合Spring 2.0 技術手冊第八章 - View 層方案、Web 框架整合
Spring 2.0 技術手冊第八章 - View 層方案、Web 框架整合
Justin Lin
 
Spring 2.0 技術手冊導讀
Spring 2.0 技術手冊導讀Spring 2.0 技術手冊導讀
Spring 2.0 技術手冊導讀
Justin Lin
 
Spring 2.0 技術手冊目錄
Spring 2.0 技術手冊目錄Spring 2.0 技術手冊目錄
Spring 2.0 技術手冊目錄
Justin Lin
 
Spring 2.0 技術手冊再版序
Spring 2.0 技術手冊再版序Spring 2.0 技術手冊再版序
Spring 2.0 技術手冊再版序
Justin Lin
 
Spring 2.0 技術手冊書名頁
Spring 2.0 技術手冊書名頁Spring 2.0 技術手冊書名頁
Spring 2.0 技術手冊書名頁
Justin Lin
 
進階主題
進階主題進階主題
進階主題
Justin Lin
 
Servlet & JSP 教學手冊第二版 - 第 11 章:簡介 JavaMail
Servlet & JSP 教學手冊第二版 - 第 11 章:簡介 JavaMailServlet & JSP 教學手冊第二版 - 第 11 章:簡介 JavaMail
Servlet & JSP 教學手冊第二版 - 第 11 章:簡介 JavaMail
Justin Lin
 
Servlet & JSP 教學手冊第二版 - 第 9 章:整合資料庫
Servlet & JSP 教學手冊第二版 - 第 9 章:整合資料庫Servlet & JSP 教學手冊第二版 - 第 9 章:整合資料庫
Servlet & JSP 教學手冊第二版 - 第 9 章:整合資料庫
Justin Lin
 
Servlet & JSP 教學手冊第二版 - 第 10 章:Web 容器安全管理
Servlet & JSP 教學手冊第二版 - 第 10 章:Web 容器安全管理Servlet & JSP 教學手冊第二版 - 第 10 章:Web 容器安全管理
Servlet & JSP 教學手冊第二版 - 第 10 章:Web 容器安全管理
Justin Lin
 
Servlet & JSP 教學手冊第二版 - 第 8 章:自訂標籤
Servlet & JSP 教學手冊第二版 - 第 8 章:自訂標籤Servlet & JSP 教學手冊第二版 - 第 8 章:自訂標籤
Servlet & JSP 教學手冊第二版 - 第 8 章:自訂標籤
Justin Lin
 
Servlet & JSP 教學手冊第二版 - 第 12 章:從模式到框架
Servlet & JSP 教學手冊第二版 - 第 12 章:從模式到框架Servlet & JSP 教學手冊第二版 - 第 12 章:從模式到框架
Servlet & JSP 教學手冊第二版 - 第 12 章:從模式到框架
Justin Lin
 
Servlet & JSP 教學手冊第二版 - 第 4 章:會話管理
Servlet & JSP 教學手冊第二版 - 第 4 章:會話管理Servlet & JSP 教學手冊第二版 - 第 4 章:會話管理
Servlet & JSP 教學手冊第二版 - 第 4 章:會話管理
Justin Lin
 
Servlet & JSP 教學手冊第二版 - 第 2 章:撰寫與設定 Servlet
Servlet & JSP 教學手冊第二版 - 第 2 章:撰寫與設定 ServletServlet & JSP 教學手冊第二版 - 第 2 章:撰寫與設定 Servlet
Servlet & JSP 教學手冊第二版 - 第 2 章:撰寫與設定 Servlet
Justin Lin
 
Servlet & JSP 教學手冊第二版 - 第 3 章:請求與回應
Servlet & JSP 教學手冊第二版 - 第 3 章:請求與回應Servlet & JSP 教學手冊第二版 - 第 3 章:請求與回應
Servlet & JSP 教學手冊第二版 - 第 3 章:請求與回應
Justin Lin
 
類別的繼承
類別的繼承類別的繼承
類別的繼承
Justin Lin
 
除錯、測試與效能
除錯、測試與效能除錯、測試與效能
除錯、測試與效能
Justin Lin
 
並行與平行
並行與平行並行與平行
並行與平行
Justin Lin
 
Python 起步走
Python 起步走Python 起步走
Python 起步走
Justin Lin
 

Viewers also liked (20)

Spring 2.0 技術手冊第十章 - 專案:線上書籤
Spring 2.0 技術手冊第十章 - 專案:線上書籤Spring 2.0 技術手冊第十章 - 專案:線上書籤
Spring 2.0 技術手冊第十章 - 專案:線上書籤
 
Spring 2.0 技術手冊第九章 - API 封裝
Spring 2.0 技術手冊第九章 - API 封裝Spring 2.0 技術手冊第九章 - API 封裝
Spring 2.0 技術手冊第九章 - API 封裝
 
Spring 2.0 技術手冊第八章 - View 層方案、Web 框架整合
Spring 2.0 技術手冊第八章 - View 層方案、Web 框架整合Spring 2.0 技術手冊第八章 - View 層方案、Web 框架整合
Spring 2.0 技術手冊第八章 - View 層方案、Web 框架整合
 
Spring 2.0 技術手冊導讀
Spring 2.0 技術手冊導讀Spring 2.0 技術手冊導讀
Spring 2.0 技術手冊導讀
 
Spring 2.0 技術手冊目錄
Spring 2.0 技術手冊目錄Spring 2.0 技術手冊目錄
Spring 2.0 技術手冊目錄
 
Spring 2.0 技術手冊再版序
Spring 2.0 技術手冊再版序Spring 2.0 技術手冊再版序
Spring 2.0 技術手冊再版序
 
Spring 2.0 技術手冊書名頁
Spring 2.0 技術手冊書名頁Spring 2.0 技術手冊書名頁
Spring 2.0 技術手冊書名頁
 
進階主題
進階主題進階主題
進階主題
 
Servlet & JSP 教學手冊第二版 - 第 11 章:簡介 JavaMail
Servlet & JSP 教學手冊第二版 - 第 11 章:簡介 JavaMailServlet & JSP 教學手冊第二版 - 第 11 章:簡介 JavaMail
Servlet & JSP 教學手冊第二版 - 第 11 章:簡介 JavaMail
 
Servlet & JSP 教學手冊第二版 - 第 9 章:整合資料庫
Servlet & JSP 教學手冊第二版 - 第 9 章:整合資料庫Servlet & JSP 教學手冊第二版 - 第 9 章:整合資料庫
Servlet & JSP 教學手冊第二版 - 第 9 章:整合資料庫
 
Servlet & JSP 教學手冊第二版 - 第 10 章:Web 容器安全管理
Servlet & JSP 教學手冊第二版 - 第 10 章:Web 容器安全管理Servlet & JSP 教學手冊第二版 - 第 10 章:Web 容器安全管理
Servlet & JSP 教學手冊第二版 - 第 10 章:Web 容器安全管理
 
Servlet & JSP 教學手冊第二版 - 第 8 章:自訂標籤
Servlet & JSP 教學手冊第二版 - 第 8 章:自訂標籤Servlet & JSP 教學手冊第二版 - 第 8 章:自訂標籤
Servlet & JSP 教學手冊第二版 - 第 8 章:自訂標籤
 
Servlet & JSP 教學手冊第二版 - 第 12 章:從模式到框架
Servlet & JSP 教學手冊第二版 - 第 12 章:從模式到框架Servlet & JSP 教學手冊第二版 - 第 12 章:從模式到框架
Servlet & JSP 教學手冊第二版 - 第 12 章:從模式到框架
 
Servlet & JSP 教學手冊第二版 - 第 4 章:會話管理
Servlet & JSP 教學手冊第二版 - 第 4 章:會話管理Servlet & JSP 教學手冊第二版 - 第 4 章:會話管理
Servlet & JSP 教學手冊第二版 - 第 4 章:會話管理
 
Servlet & JSP 教學手冊第二版 - 第 2 章:撰寫與設定 Servlet
Servlet & JSP 教學手冊第二版 - 第 2 章:撰寫與設定 ServletServlet & JSP 教學手冊第二版 - 第 2 章:撰寫與設定 Servlet
Servlet & JSP 教學手冊第二版 - 第 2 章:撰寫與設定 Servlet
 
Servlet & JSP 教學手冊第二版 - 第 3 章:請求與回應
Servlet & JSP 教學手冊第二版 - 第 3 章:請求與回應Servlet & JSP 教學手冊第二版 - 第 3 章:請求與回應
Servlet & JSP 教學手冊第二版 - 第 3 章:請求與回應
 
類別的繼承
類別的繼承類別的繼承
類別的繼承
 
除錯、測試與效能
除錯、測試與效能除錯、測試與效能
除錯、測試與效能
 
並行與平行
並行與平行並行與平行
並行與平行
 
Python 起步走
Python 起步走Python 起步走
Python 起步走
 

Similar to Spring 2.0 技術手冊第四章 - Spring AOP

Java Script 引擎技术
Java Script 引擎技术Java Script 引擎技术
Java Script 引擎技术
bigqiang zou
 
Uliweb框架思想与编程
Uliweb框架思想与编程Uliweb框架思想与编程
Uliweb框架思想与编程modou li
 
Spring框架,技术详解及使用指导
Spring框架,技术详解及使用指导Spring框架,技术详解及使用指导
Spring框架,技术详解及使用指导yiditushe
 
Java SE 7 技術手冊第二章草稿 - 從 JDK 到 IDE
Java SE 7 技術手冊第二章草稿 - 從 JDK 到 IDEJava SE 7 技術手冊第二章草稿 - 從 JDK 到 IDE
Java SE 7 技術手冊第二章草稿 - 從 JDK 到 IDE
Justin Lin
 
Js的国(转载)
Js的国(转载)Js的国(转载)
Js的国(转载)Leo Hui
 
所谓闭包
所谓闭包所谓闭包
所谓闭包ilovey4
 
所谓闭包
所谓闭包所谓闭包
所谓闭包youzitang
 
千呼萬喚始出來的Java SE 7
千呼萬喚始出來的Java SE 7千呼萬喚始出來的Java SE 7
千呼萬喚始出來的Java SE 7
javatwo2011
 
Php设计模式介绍
Php设计模式介绍Php设计模式介绍
Php设计模式介绍cyf5513
 
Lucene 全文检索实践
Lucene 全文检索实践Lucene 全文检索实践
Lucene 全文检索实践yiditushe
 
About closure
About closureAbout closure
About closure
otakustay
 
Clojure简介与应用
Clojure简介与应用Clojure简介与应用
Clojure简介与应用
Robert Hao
 
beidakejian
beidakejianbeidakejian
beidakejian
hanxuebing
 
Compiler for Dummy 一點都不深入的了解 Compiler, Interpreter 和 VM
Compiler for Dummy 一點都不深入的了解 Compiler, Interpreter 和 VMCompiler for Dummy 一點都不深入的了解 Compiler, Interpreter 和 VM
Compiler for Dummy 一點都不深入的了解 Compiler, Interpreter 和 VM
Li Hsuan Hung
 
Coding guideline
Coding guidelineCoding guideline
Coding guideline斯理 衛
 
Java面试题集
Java面试题集Java面试题集
Java面试题集yiditushe
 
用JAX-RS和Jersey完成RESTful Web Services
用JAX-RS和Jersey完成RESTful Web Services用JAX-RS和Jersey完成RESTful Web Services
用JAX-RS和Jersey完成RESTful Web Services
javatwo2011
 

Similar to Spring 2.0 技術手冊第四章 - Spring AOP (20)

Java Script 引擎技术
Java Script 引擎技术Java Script 引擎技术
Java Script 引擎技术
 
Uliweb框架思想与编程
Uliweb框架思想与编程Uliweb框架思想与编程
Uliweb框架思想与编程
 
Spring框架,技术详解及使用指导
Spring框架,技术详解及使用指导Spring框架,技术详解及使用指导
Spring框架,技术详解及使用指导
 
Java SE 7 技術手冊第二章草稿 - 從 JDK 到 IDE
Java SE 7 技術手冊第二章草稿 - 從 JDK 到 IDEJava SE 7 技術手冊第二章草稿 - 從 JDK 到 IDE
Java SE 7 技術手冊第二章草稿 - 從 JDK 到 IDE
 
Js的国(转载)
Js的国(转载)Js的国(转载)
Js的国(转载)
 
所谓闭包
所谓闭包所谓闭包
所谓闭包
 
所谓闭包
所谓闭包所谓闭包
所谓闭包
 
千呼萬喚始出來的Java SE 7
千呼萬喚始出來的Java SE 7千呼萬喚始出來的Java SE 7
千呼萬喚始出來的Java SE 7
 
Php设计模式介绍
Php设计模式介绍Php设计模式介绍
Php设计模式介绍
 
Lucene 全文检索实践
Lucene 全文检索实践Lucene 全文检索实践
Lucene 全文检索实践
 
About closure
About closureAbout closure
About closure
 
Clojure简介与应用
Clojure简介与应用Clojure简介与应用
Clojure简介与应用
 
beidakejian
beidakejianbeidakejian
beidakejian
 
Compiler for Dummy 一點都不深入的了解 Compiler, Interpreter 和 VM
Compiler for Dummy 一點都不深入的了解 Compiler, Interpreter 和 VMCompiler for Dummy 一點都不深入的了解 Compiler, Interpreter 和 VM
Compiler for Dummy 一點都不深入的了解 Compiler, Interpreter 和 VM
 
SCJP ch02
SCJP ch02SCJP ch02
SCJP ch02
 
Coding guideline
Coding guidelineCoding guideline
Coding guideline
 
Java面试题集
Java面试题集Java面试题集
Java面试题集
 
用JAX-RS和Jersey完成RESTful Web Services
用JAX-RS和Jersey完成RESTful Web Services用JAX-RS和Jersey完成RESTful Web Services
用JAX-RS和Jersey完成RESTful Web Services
 
getPDF.aspx
getPDF.aspxgetPDF.aspx
getPDF.aspx
 
getPDF.aspx
getPDF.aspxgetPDF.aspx
getPDF.aspx
 

More from Justin Lin

Ch14 簡介 Spring Boot
Ch14 簡介 Spring BootCh14 簡介 Spring Boot
Ch14 簡介 Spring Boot
Justin Lin
 
Ch12 Spring 起步走
Ch12 Spring 起步走Ch12 Spring 起步走
Ch12 Spring 起步走
Justin Lin
 
Ch11 簡介 JavaMail
Ch11 簡介 JavaMailCh11 簡介 JavaMail
Ch11 簡介 JavaMail
Justin Lin
 
Ch10 Web 容器安全管理
Ch10 Web 容器安全管理Ch10 Web 容器安全管理
Ch10 Web 容器安全管理
Justin Lin
 
Ch09 整合資料庫
Ch09 整合資料庫Ch09 整合資料庫
Ch09 整合資料庫
Justin Lin
 
Ch08 自訂標籤
Ch08 自訂標籤Ch08 自訂標籤
Ch08 自訂標籤
Justin Lin
 
Ch07 使用 JSTL
Ch07 使用 JSTLCh07 使用 JSTL
Ch07 使用 JSTL
Justin Lin
 
Ch06 使用 JSP
Ch06 使用 JSPCh06 使用 JSP
Ch06 使用 JSP
Justin Lin
 
Ch05 Servlet 進階 API、過濾器與傾聽器
Ch05 Servlet 進階 API、過濾器與傾聽器Ch05 Servlet 進階 API、過濾器與傾聽器
Ch05 Servlet 進階 API、過濾器與傾聽器
Justin Lin
 
Ch04 會話管理
Ch04 會話管理Ch04 會話管理
Ch04 會話管理
Justin Lin
 
Ch02 撰寫與設定 Servlet
Ch02 撰寫與設定 ServletCh02 撰寫與設定 Servlet
Ch02 撰寫與設定 Servlet
Justin Lin
 
CH1. 簡介 Web 應用程式
CH1. 簡介 Web 應用程式CH1. 簡介 Web 應用程式
CH1. 簡介 Web 應用程式
Justin Lin
 
14. 進階主題
14. 進階主題14. 進階主題
14. 進階主題
Justin Lin
 
13.並行、平行與非同步
13.並行、平行與非同步13.並行、平行與非同步
13.並行、平行與非同步
Justin Lin
 
12. 除錯、測試與效能
12. 除錯、測試與效能12. 除錯、測試與效能
12. 除錯、測試與效能
Justin Lin
 
11. 常用內建模組
11. 常用內建模組11. 常用內建模組
11. 常用內建模組
Justin Lin
 
10. 資料永續與交換
10. 資料永續與交換10. 資料永續與交換
10. 資料永續與交換
Justin Lin
 
9. 資料結構
9. 資料結構9. 資料結構
9. 資料結構
Justin Lin
 
8. open() 與 io 模組
8. open() 與 io 模組8. open() 與 io 模組
8. open() 與 io 模組
Justin Lin
 
7. 例外處理
7. 例外處理7. 例外處理
7. 例外處理
Justin Lin
 

More from Justin Lin (20)

Ch14 簡介 Spring Boot
Ch14 簡介 Spring BootCh14 簡介 Spring Boot
Ch14 簡介 Spring Boot
 
Ch12 Spring 起步走
Ch12 Spring 起步走Ch12 Spring 起步走
Ch12 Spring 起步走
 
Ch11 簡介 JavaMail
Ch11 簡介 JavaMailCh11 簡介 JavaMail
Ch11 簡介 JavaMail
 
Ch10 Web 容器安全管理
Ch10 Web 容器安全管理Ch10 Web 容器安全管理
Ch10 Web 容器安全管理
 
Ch09 整合資料庫
Ch09 整合資料庫Ch09 整合資料庫
Ch09 整合資料庫
 
Ch08 自訂標籤
Ch08 自訂標籤Ch08 自訂標籤
Ch08 自訂標籤
 
Ch07 使用 JSTL
Ch07 使用 JSTLCh07 使用 JSTL
Ch07 使用 JSTL
 
Ch06 使用 JSP
Ch06 使用 JSPCh06 使用 JSP
Ch06 使用 JSP
 
Ch05 Servlet 進階 API、過濾器與傾聽器
Ch05 Servlet 進階 API、過濾器與傾聽器Ch05 Servlet 進階 API、過濾器與傾聽器
Ch05 Servlet 進階 API、過濾器與傾聽器
 
Ch04 會話管理
Ch04 會話管理Ch04 會話管理
Ch04 會話管理
 
Ch02 撰寫與設定 Servlet
Ch02 撰寫與設定 ServletCh02 撰寫與設定 Servlet
Ch02 撰寫與設定 Servlet
 
CH1. 簡介 Web 應用程式
CH1. 簡介 Web 應用程式CH1. 簡介 Web 應用程式
CH1. 簡介 Web 應用程式
 
14. 進階主題
14. 進階主題14. 進階主題
14. 進階主題
 
13.並行、平行與非同步
13.並行、平行與非同步13.並行、平行與非同步
13.並行、平行與非同步
 
12. 除錯、測試與效能
12. 除錯、測試與效能12. 除錯、測試與效能
12. 除錯、測試與效能
 
11. 常用內建模組
11. 常用內建模組11. 常用內建模組
11. 常用內建模組
 
10. 資料永續與交換
10. 資料永續與交換10. 資料永續與交換
10. 資料永續與交換
 
9. 資料結構
9. 資料結構9. 資料結構
9. 資料結構
 
8. open() 與 io 模組
8. open() 與 io 模組8. open() 與 io 模組
8. open() 與 io 模組
 
7. 例外處理
7. 例外處理7. 例外處理
7. 例外處理
 

Spring 2.0 技術手冊第四章 - Spring AOP

  • 1. 。一之點重的節章個這是也 用使何如解了您讓,心 Spring AOP 核的賴依所能功 子或架框子些一中 是也 而,術 Spring Spring AOP 技種一的 現實是 AOP ,型 模 計 設 個 兩 的 成 相 輔 相 以 可 是 S pring AOP 們 它,觸 抵 互 相 不 並) ( 跟 OOP O bject-oriented programming AOP 。釋解得獲將都中節章個這在,詞名 的關相 與樣各式各上以,) AOP (合縫的式程用應與及計設 W eave 的 Aspect 在重著 , 為之稱件 A spect-oriented programming Aspect 物 殊 特 的 樣 這,件 物 個 一 為 計 設 來 出 立 獨 Crossing-cutting concerns 將, 為 稱 輯 邏 的 樣 這 ,) Cross-cutting concerns 、 S ecurity Logging 如例(輯邏務服統系的關無輯邏務商與入插中程流的務服個一在 Spring AOP 4
  • 2. Spring 2.0 良信林(冊手術技 – http://openhome.cc ) 4.1 AOP 入門 過觸接未尚於對, AOP 名全 Aspect-oriented programming AOP 的 是像,解理以難人令詞名語術的象抽多許中 ,說來人 A OP Cross-cutting (制機理代從先將,中節小個這在,等 concerns A spect W eave 、 、 S pring 紹介 中 從 , 式 程 範 示的單 簡 且 際 實 個 一 看 來 ) 式 方 種 一 的 現 實 AOP AOP 。語術種各與念觀的 4.1.1 從代理機制初探 AOP 子例的見常單簡個一從先,邊一到放詞名寫縮文英個這 將先且暫 AOP 需常很中式程,作動) (誌日有含中當子例個這,題議個一看來 L ogging 為作是或,程過作運式程視檢後事在便以,錄記下作件事或作動些某為要 。訊資的時錯除 ,息訊誌日下留時法方些某行執在要需您當,子例的單簡最個一看來 : 寫 撰下如 會 能 可 您 , 的 覺 直 package onlyfun.caterpillar; import java.util.logging.*; public class HelloSpeaker { private Logger logger = Logger.getLogger(this.getClass().getName()); public void hello(String name) { // 錄記下留時始開行執法方 錄 logger.log(Level.INFO, "hello method starts...."); // 能功要主式程 System.out.println("Hello, " + name); // 錄記下留前畢完行執法方 錄記下留前畢完行執法方 logger.log(Level.INFO, "hello method ends...."); } 4 2
  • 3. 4 3 :面介 IHello 個一義定先首,說來子例的際實個舉 。責職關相務商留保僅以可就中當件物理代被此如,件 物的理代被叫呼再候時的要需在並,務服關相等誌日現實以可中件物理 代在,面介個一同現實須必件物理代被與件物理代,中現實的理代態靜在 理代態靜 。) D ynamic proxy (理代態動與) S tatic proxy ( 理代 態靜:式方 理代種兩論討邊這在,題問個這決解來制機) ( 理 代用使以可 P roxy 。 去 移 中 式 程 的 有既從 務 服 關 相 些 這 將 的 單簡法無您,碼式程的作動誌日下留有所改修要需將麼那,務服的)等理 管易交、查檢限權或(誌日要需再不若,法寫的上以用使,面方一另 。 碼式程 的 務 服 或 作 動 的 關相不 責 職 件 物 與 些 這 於少還 許 或 , 碼 式 程 的 佔 所責職的身本件物,責職的有負該身本件物了淆混至甚,重加形更擔負的 件物得使會,)等等理管易交、查檢限權如例(中之件物了入混也作動關 相 的 責 職 身 本 件 物 非 些 一 有 , 作 動 誌 日 有 只 不) S ervice (務 服 的 要 需 果 如 。大加度難困的碼式程誌日護維得使這,碼式程的作動誌日些這寫撰處到您 成造必勢法寫的上以,求需有都處到作動的誌日種這中式程果如想想 。責職的外額了加增 Speaker Hello- 得使這,)字文等 "Hello" 示顯(輯邏務商 HelloSpeaker 於屬不並作 動 個 幾 這 的 誌 日,說 來 HelloSpeaker 於 對,中 別 類 H elloSpeaker ) cutting C ross- (入切橫碼式程行幾這的誌日而然,作動誌日上加後前的行執法 方在,計設式程的上以如是就法作的單簡最,錄記下留能都時畢完行執與 始開行執法方望希您,時法方 hello() 行執當,中別類 HelloSpeaker 在 } Chapter 4 Spring AOP
  • 4. Spring 2.0 良信林(冊手術技 – http://openhome.cc ) StaticProxyDemo IHello.java package onlyfun.caterpillar; public interface IHello { public void hello(String name); } 的輯邏務商現實讓後然 HelloSpeaker 現實別類 IHello :如例,面介 StaticProxyDemo HelloSpeaker.java package onlyfun.caterpillar; public class HelloSpeaker implements IHello { public void hello(String name) { System.out.println("Hello, " + name); } } ,中其入插碼式程的誌日何任有沒在現中別類 HelloSpeaker 在,到看以可 介 現實要也樣同件物理代,中之件物理代至放被將現實的務服誌日 IHello :如例,面 StaticProxyDemo HelloProxy.java package onlyfun.caterpillar; import java.util.logging.*; public class HelloProxy implements IHello { private Logger logger = Logger.getLogger(this.getClass().getName()); private IHello helloObject; public HelloProxy(IHello helloObject) { this.helloObject = helloObject; } 4 4
  • 5. Chapter 4 Spring AOP public void hello(String name) { // 務服誌日 log("hello method starts...."); // 輯邏務商行執 helloObject.hello(name); // 務服誌日 log("hello method ends...."); } private void log(String msg) { logger.log(Level.INFO, msg); } } 誌 日 排 安 以 可 後 前 輯 邏 務 商 現 實 正 真,中 法 方 HelloProxy hello() 的別類 在 。件物理代用使何如看看來式程試測個一寫撰際實,務服 StaticProxyDemo ProxyDemo.java package onlyfun.caterpillar; public class ProxyDemo { public static void main(String[] args) { IHello proxy = new HelloProxy(new HelloSpeaker()); proxy.hello("Justin"); } } 物理代被個一它給須必時件物理代構建,件物理代是的行執叫呼中式程 來,面介 為面介作操換轉須必,時件物理代的回取作操在得記,件 IHello :果結的行執際實下一看 4
  • 6. 4 6 。理原本基的理代解了您讓在是,的目 的理代態靜紹介邊這在,任勝法無就時大稍模規式程在理代態靜,理代行 進法方個每為要必勢,多很法方的理代要果如且而,件物的型類種一於務 服只面介個一的件物理代,的到看所您如而然,例範本基的理代態靜是這 程流作運的制機理代 4.2 圖 :程流作運的制機理 代出看步一進更來式方的解圖從以可,責職的它於心專以可 HelloSpeaker ,作動誌日入介必不時寫撰在 HelloSpeaker 得使這,作動的誌日上加後前 其在並,hello() 行執來 HelloSpeaker 的正真理代將 件物理代 HelloProxy 果結行執案專 4.1 StaticProxyDemo 圖 ) – http://openhome.cc 良信林(冊手術技 Spring 2.0
  • 7. Chapter 4 Spring AOP 文 在現出都何為息訊誌日的 圖:問會人多很 4.1 " Hello, Justin" ? 嗎 錯 有 果 結 行 執 例 範 ?) 後 之 在 是 許 也 果 結 的 行 執 您 (前 之 字 不並作動誌日,行進來緒行執個一另由是作動的誌日,道知要 執有實確作動誌日於在點重的例範,程流式程)入介或(響影 來用是不也作動誌日,序順的現出台控主於息訊在是不而,行 順的息訊現出台控主到看想的真果如。用之序順行執式程測預 全份部的誌日將麼那,序順叫呼的法方與件物中式程合符,序 。可即出輸準標成改部 理代態動 件 物 定 特 為 必 不 您, 的 能 功 理 代 態 動 發 開 助 協 可 了 入 加 後 之 JDK 1.3 API 在 者理處個一得使以可,理代態動用使,件物理代的定特寫撰法方與 作實須必計設別類的者理處個一,先首。件物個各於務服) H andler ( java.lang.reflect.InvocationHandler 計 設 如 例,明 說 行 進 來 例 實 以,面 介 LogHandler :別類 個一 DynamicProxyDemo LogHandler.java package onlyfun.caterpillar; import java.util.logging.*; import java.lang.reflect.*; public class LogHandler implements InvocationHandler { private Logger logger = Logger.getLogger(this.getClass().getName()); private Object delegate; public Object bind(Object delegate) { this.delegate = delegate; return Proxy.newProxyInstance( delegate.getClass().getClassLoader(), 4 7
  • 8. Spring 2.0 良信林(冊手術技 – http://openhome.cc ) delegate.getClass().getInterfaces(), this); } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = null; try { log("method starts..." + method); result = method.invoke(delegate, args); logger.log(Level.INFO, "method ends..." + method); } catch (Exception e){ log(e.toString()); } return result; } private void log(String message) { logger.log(Level.INFO, message); } } 物理代個一立建法方態靜 用使是念概的要主 Proxy.newProxyInstance() 的立建所作操以可您後之,面介的理代要所知告須必時件物理代立建,件 ,法方 的 行執會時作操次每在,件物理代 InvocationHandler invoke() 的行執要上際實,數參行執與稱名法方的件物理代被入傳會法方 invoke() ,作動誌日上加後前 在您, method.invoke() 由交法方 method.invoke() 。果結傳回的後過行執法方際實是件物的回傳 method.invoke() :如例,面介的理代要所義定須必樣同,理代態動現實要 4 8
  • 9. Chapter 4 Spring AOP DynamicProxyDemo IHello.java package onlyfun.caterpillar; public interface IHello { public void hello(String name); } 的輯邏務商現實讓後然 HelloSpeaker 現實別類 IHello :如例,面介 DynamicProxyDemo HelloSpeaker.java package onlyfun.caterpillar; public class HelloSpeaker implements IHello { public void hello(String name) { System.out.println("Hello, " + name); } } 介 的中案專 前之跟這,了到現發許或您的尖眼 StaticProxyDemo IHello 。現 呈 整 完 的 例 範 了 為 是 來 出 寫 撰 邊 這 在,容 內 的 同 相 是 H elloSpeaker 、面 定綁來法方 的 用使要您,式程的試測個一寫撰來下接 LogHandler bind() :示所下如,件物理代被 DynamicProxyDemo ProxyDemo.java package onlyfun.caterpillar; public class ProxyDemo { public static void main(String[] args) { LogHandler logHandler = new LogHandler(); IHello helloProxy = (IHello) logHandler.bind(new HelloSpeaker()); helloProxy.hello("Justin"); } } 4
  • 10. 4 1 。碼 式程行一 何任改 修需不 身本式程 用應而 ,離脫 中式 程用應 從 接 直 Aspect 些這將以可又,候時的務服關相要需不而,務服供提中之式程用應入介以 可,候時的要必在,外之式程用應於立獨以可 Aspect ,下 之 計 設 的 好 在 。 為即詞名寫縮 AOP ,Aspect-oriented programming 的謂所是就這,件物 的楚清責職個 Aspect 一的件物務商定特入介不、用通為計設) C ross-cutting concerns (作動些 這將 您 , 務 服 或 作 動 的類這 等 誌 日 是 像 以 可 的 指 所 的中 Aspect AOP 。) A spect (面切為之稱件物的樣這 , LogHandler是或 HelloProxy 的範 示 中 例 範 前 之是像 , 件 物 務 服 個 一 為 計設,來出取提務任或作動的關無輯邏務商與等誌日將件物理代用使 。) C ross-cutting concern (點 切 關切橫為之稱中 在作動的樣這誌日 AOP ,中程流行執式程的 HelloSpeaker 入) C ross-cutting (切橫碼式程的誌日 AOP ,說 來語術的 在,重加責職的 HelloSpeaker 得使這,作動誌日入插須 必卻,字文呼招示顯是責職的身本 H elloSpeaker ,中子例的頁 如 4.2 AOP ?係關何有 與子例個這,上題議的 到回 AOP 。在存的作動誌日到識意用不它,作動的誌日於關有何 任入插用不也 HelloSpeaker 而,面介與件物定特於務服再不 LogHandler 果結行執的案專 4.3 DynamicProxyDemo 圖 :果結的行執下一看來 ) – http://openhome.cc 良信林(冊手術技 Spring 2.0
  • 11. 4 11 :的純單很是 程 流 務 商 的 來 原 如 例,涵 意 的 Cross-cutting concerns 出調強可明說片圖以 。 Cross-cutting concerns 為之稱被中語術的 在作動些這,中之程流 AOP 理 處 的 件 物 個 各 至 插 安 到 見 被 常 中 之 式 程 用 應 些 一 在 ,) (務服的 S ervice 面層統系等) T ransaction (易交、查檢) S ecurity (全安如,作動的類這 誌 日 於 似 類 外 另,中 之 程 流 務 商 的 責 負 所 身 本 HelloSpeaker 至 入) cutting C ross- (切橫被先原作動的誌日,中子例的案專 DynamicProxyDemo 在 Cross-cutting concern AOP : 念 觀 與 語 術 的 紹 介 以 照 對 一 逐 來,例 範 的 制 機 理 代 紹 介 前之以將邊這,義意詞名其解理易容不並上面字從單,象抽於過都語術詞 名多許的 於關有, AOP Aspect-Oriented Programming 為名全 AOP 4.1.2 AOP 觀念與術語 。詞名文中的服信人令更無有看後日待留,題問詞名 的譯翻文中將,現呈來語術詞名文英的本原 以將,中節章 AOP 的來下接此因,詞名譯翻文中的一統個有沒也在現語術詞名文 英些這且而,口拗很在實文中成翻要語術詞名文英關相的 AOP Chapter 4 Spring AOP
  • 12. 4 12 專 DynamicProxyDemo 在 如 例,改 修 的 何 任 作 用 不 件 組 用 重 可 的 中 式 程 用 應,離脫中式程用應從上馬以可也,候時的務服要需不,上之式程用應至 ) (合縫,候時的務服該要需在,來出立獨中程流務商從之將,認 W eave 辨的 Aspect 於重著中 在。例實體具個一的 AOP 是就語術的 Aspect AOP 在別類 L ogHandler ,別類 LogHandler 個一為計設作動的誌日將,中案專 DynamicProxyDemo 在如例。 Aspect 為之稱件物些這,件物的用重可立獨 個 各 計 設,來 起 集 收 Cross-cutting concerns 的中之輯邏務商個各於落散將 Aspect 。雜複為更寫撰的式程 或 輯 邏 的 身 本 件 物 務 商 得 使,中 之 輯 邏 務 商 於 雜 混 Cross-cutting concerns ,面方一另,譯編新重後然,碼式程的務服誌日寫撰有所改修須必則,務 服該除移是或改修能功誌日的中件物將要天今您若,高增本成的式程護維 得 使 會,中 程 流 之 件 物 的 務 商 某 責 負 在 寫 撰 接 直 若 Cross-cutting concerns 二之解圖 4.5 AOP 圖 :念概的 與 Cross-cutting concerns cutting Cross- 出示表解圖下以用使可則,段片式程查檢全安、誌日的關相入 寫的生生硬被像中碼式程的件物,務服等查檢全安與誌日入加要了為在現 一之解圖 4.4 AOP 圖 ) – http://openhome.cc 良信林(冊手術技 Spring 2.0
  • 13. 4 13 。後前的法方 至用應要 Advice 些哪明說, 寫撰中 Pointcut 或檔義定在以可 Annotation 您, 說 的 體 具 中 Spring 2.0 在。 務 服 供 提 上 式 程 用 應 至 合 縫 將, 時 Advice 式示表 Pointcut 合符法方的叫呼當, 的趣興感了義定 Jointpoint Pointcut Pointcut 。候時的生發外例個某中法方是或 ,) 有 都 者 兩 或 (後 之 或 前 之 行 執 被 法 方 個 某 是 能 可 機 時 行 執, Jointpoint 的法方援支只 S pring 。機時的行執被中式程用應在 是就,說來 Advice 體 具, Joinpoint 為之稱機時或點的程流務商入加時行執式程用應在 Advice Joinpoint 。務服的供 提要所或為行的 Cross-cutting concerns 了括包中 A dvice 。例實體具個一 的 Advice 是就,法方 的 中案專 invoke() LogHandler DynamicProxyDemo 是像,的作實何如是碼式程誌日括包會中 Advice ,言而作動的 誌日以。 Advice 為之稱作實體具的 Cross-cutting concerns 對中當 Aspect Advice 。合耦生發架框式程用應的前目與 而務服些某了入加前目為因會不而,中之式程用應的它其至用應件組些這 將以可您,性用重的件組些這高提可而因,中之件組式程用應的用重可在 API 現出會不 的關相務服與,說的體具,在存否是件物的務服供提道知用 AOP 不 它,式 方 計 設 的 以,說 來 件 組 的 用 重 可 中 式 程 用 應 於 對,面 方 一 另 。碼式程的身本改修用不並時務服誌日要 需 它 在,件 組 的 用 重 可 中 式 程 用 應 是 就 色 角 的 表 代 所 的中案 HelloSpeaker Chapter 4 Spring AOP
  • 14. Spring 2.0 良信林(冊手術技 – http://openhome.cc ) Target 個一 Advice 如例,件物標目或象對的用應被 DynamicProxyDemo 中案專 的 HelloSpeaker 的 中 是就 LogHandler Advice Target 。 Introduction 類該改修用不而,為行加增其為以可 ,別類的存現個一於對 I ntroduction 期時行執在,別類的成完譯編、寫撰已個某為以可,說的體具,式程的別 。碼式程行一何任增新或改修用不而,為行或法方些一入加態動 Proxy E xpert One-on-One J2EE Development WIthout EJB ,中 書 一》 《在 R od 的要主個五有作實的 ,到提有中章八第在 Johnson J uergen Hoeller 、 A OP 、 D ynamic Proxies 、 :略策 D ynamic Byte Code Generation J ava Code 。 Generation 、 U se of a Custon Class Loader 、 L anguage Extensions 機理代過紹介例範式程的際實用使經已,中理代態動與理代態靜前之在 。 面 介 的 何 任 理 代 於 用 可,成 完 來 理 代 態 動 過 透 是 要 主 的 S pring AOP ,制 留 遺 些 一 是 像,別 類 理 代 以 用,理 代 S pring 用使以可也 CGLIB ,面 方 一 另 L egacy classes 。) (別類 Weave Advice 在,) (合 縫 為 之 稱 程 過 的 上 之 件 物 至 用 應 被 W eave AOP 的合縫中 (期 時 入 載 別 類、) (期 時 譯 編:點 間 時 個 幾 有 式 方 C ompile time C lassload time 。) R untime (期時行執、) 的體具詞名關相 的過紹介上以將,例實的 DynamicProxyDemo 合結 AOP :識認與解理的詞名個一每對於助有,示表來片圖用使 4 14
  • 15. Chapter 4 Spring AOP 圖 4.6 AOP 意示詞名個各的 4.1.3 Spring AOP 在別差的要主,式方作實同不的念概 對其有會架框 的同不 AOP AOP ) (合縫被何如們它及以,度程富豐的 Pointcuts A spects 、 的供提所於 W eave 。 等 式 方 的 理代 、 ) 式 方 義 定 的 Pointcuts 是像(式程用應至 的定特用使不而,寫撰來言語式程 用是 Spring Advices Java 的 AOP 的 寫 撰, 或案檔態組 用使以可時 Pointcuts 義 定 在, 言 語 XML Annotation 用以可就,法語的定特習學必不您,悉熟很都說來員人發開 於對式方 Java Java 。 用運來式格 與言語式程 的悉熟 XML Spring AOP 作實會 的 , API 現實來式方的 作實以擇選若 Advices Spring AOP AOP 的範規所) Alliance h ttp://www.sourceforge.net/ projects/aopalliance ( 這,) (畫計合聯的成組所體團多許由是 A OP Alliance ,面 介 J oint project 對是的目,範規面介的來出訂制循遵須必求要作實的 於對體團些 AOP Java 4 1
  • 16. 4 16 。 理原的 作 運 後 背 其 解 理 易 容 會 , 時 式 方 定 設 AOP 的新 Spring 2.0 用使在,節細多許的 Spring AOP 握掌以可您是處好,式方 種 這是就 的 紹 介 要 先 首 , 時 Spring AOP 紹 介 始 開一章 本 , 件 物 理 代 定 設 並, Advice 義定來 的中當AOP API Spring 作實須必您,式方的 現實 AOP 本版前先或 Spring 1.2 是就也,式方的 Spring API 作實統傳是種一第 。式方的 現實種三了供提中 AOP 在 Spring 2.0 。性裝封的件物壞破會 Joinpoints 的員成 援支,為認中學哲計 Field 設的 Spring 在為因是這, Jointpoints 的員成 援支不 ,用應被Field S pring 後前的行執法方在將 Advices 是就也, 的法方援支只 Joinpoints Spring 。用使來) ( L egacy classes 別類舊是或別類) T hird-party (方三第的碼始原動更法無些一讓是上本基 式方個這且而,理代行進法無法方的 為告宣被於對以所,別類子生產 final 須 必 於 由,式 方 的 Proxy classes 用 使,低 降 度 合 耦 的 間 之 此 彼 件 組 的 式 程 用應 讓 以 可 這 , 先 優 為式方 的 面 介 作 實 以 該 應 您 , 中 在 Spring AOP 。) P roxy classes ( 別 類 理代為 作 別 類 子 個 一 生 產 Targets為 CGLIB 用使會 Spring 則 , 面 介 作 實 不果如 , 理 代 態 動 行 進 來 java.lang.reflect.Proxy 用使會期時行執在 則,面介的好義定先預作 Spring 實 Targets讓以可您, Targets 至入導期時行執在是 的 Advices Spring 。定設件物 理代的有所成完您為 Spring 由,示 標 接 直 中 之 別 類 在,式 方 的 Annotation 用使擇選以可也您。 入導 Advices Targets 為以可就,訊資關相義定中 檔定設在接直,面介何任作實不以可 的您,中 Advices 在 Spring 2.0 。性植移可的間 之式程用應 Java 的同不在別類作實 AOP 加增以,化準標面介作實 的 AOP ) – http://openhome.cc 良信林(冊手術技 Spring 2.0
  • 17. 4 17 。定設成完可即 Annotation 的當適記標上 Advice 在要只,定設的瑣繁作中件文 XML 在用不是 處 好,作 運 以 可 才 本 版 的 上 以 JDK 5.0 在須必式方種這以所, Annotation 到用使於由,援支 Annotation 的 @AspectJ 用使是種三第 。面介的定特作實用不 且而Advice , 多許潔 簡 式 方 種 一 第 比 會上 定 設 在 , 籤 標 < aop> 的新 Spring 2.0 用使並 ,定設 的 XML Schema XML 於基 用 使 須 必 您 , 定 設 的 於 基 是 種 二 第 Chapter 4 Spring AOP
  • 18. Spring 2.0 良信林(冊手術技 – http://openhome.cc ) 4.2 Advices ,別類個一是就說來體具中 在,輯邏正真的 Advices 了作 實 Aspect Java 由。) 多許理管 中集來別類個一由(法 方個一為 計設的度粒細 更或 Advices 是像, 的同不種幾了供提 Targets ,同不機時的 至合縫於 S pring Advices 小個這在 。 Before Advice 、 、 A fter Advice、 A round Advice T hrow Advice 。 識認始開 來 用使、寫 撰從以可您, 中節 Advices Spring AOP 4.2.1 Before Advice 現實以可您,叫呼被前之行執法方的件物標目在會 Before Advice 作實來 面介 org.springframework.aop.MethodBeforeAdvice Before Advice :示所 下如義定 的面介該,輯 邏的 package org.springframework.aop; public interface MethodBeforeAdvice extends BeforeAdvice { void before(Method method, Object[] args, Object target) throws Throwable; } ,面 介 自承繼 ,到看以可中義定在 M ethodBeforeAdvice BeforeAdvice (面 介 籤 標 是 都 者 兩 後 , 面 介 BeforeAdvice 自承繼又面介 Advice 而 T ag 承繼 interface ,法方 何 任 義 定 無 而 示 標 作 用 是 只, ) M ethodBeforeAdvice 執法方的定指所) (件物標目在會法方 BeforeAdvice b efore() , 了 T arget ,件物標目及數引、例實 的行執被得取以可您,行執被前之行 M ethod before() 之畢完行執法方 在,果 結 的 何 任 回 傳 不 以 所 , 為 告 宣 上 法 方 void before() 。 行 執 被 會 就法方 的 上 件 物 標 目 則 否,外 例 出 丟 您 非 除 , 後 的作實須必件物標目義定先首, 用使 何 如 範 示 來 例 實 以 Before Advice :面介 4 18
  • 19. Chapter 4 Spring AOP BeforeAdviceDemo IHello.java package onlyfun.caterpillar; public interface IHello { public void hello(String name); } 個一義定著接 HelloSpeaker 現實其讓,別類 IHello :面介 BeforeAdviceDemo HelloSpeaker.java package onlyfun.caterpillar; public class HelloSpeaker implements IHello { public void hello(String name) { System.out.println("Hello, " + name); } } , 下 況 情 的 改 修 何 任 行進它 對 不 在 , 畢 完 寫 撰 經 已 HelloSpeaker 在現 到拿您是這下一像想,息訊些一錄記以可,前之行執法方 hello() 在要想您 作實以可您。務服的誌日些一加增它對想但,碼始原有沒您,件組個一的 MethodBeforeAdvice :如例,面介 BeforeAdviceDemo LogBeforeAdvice.java package onlyfun.caterpillar; import java.lang.reflect.Method; import java.util.logging.Level; import java.util.logging.Logger; import org.springframework.aop.MethodBeforeAdvice; public class LogBeforeAdvice implements MethodBeforeAdvice { private Logger logger = Logger.getLogger(this.getClass().getName()); 4 1
  • 20. Spring 2.0 良信林(冊手術技 – http://openhome.cc ) public void before(Method method, Object[] args, Object target) throws Throwable { logger.log(Level.INFO, "method starts..." + method); } } ,碼式程的訊資錄記些一了入加您,中作實的法方 before() 在 的要需給務服供提以可,務服的立獨個一為計設被別類 LogBeforeAdvice : 義 定 下 如 中 檔義定 在 要 只 著 接 , 件 物 BeforeAdviceDemo beans-config.xml <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"> <bean id="logBeforeAdvice" class="onlyfun.caterpillar.LogBeforeAdvice"/> <bean id="helloSpeaker" class="onlyfun.caterpillar.HelloSpeaker"/> <bean id="helloProxy" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="proxyInterfaces" value="onlyfun.caterpillar.IHello"/> <property name="target" ref="helloSpeaker"/> <property name="interceptorNames"> <list> <value>logBeforeAdvice</value> </list> </property> </bean> </beans> 4 2
  • 21. Chapter 4 Spring AOP 了用使還您,外之例實件物的 及 Advice 立建了除到意注 Target 會別類個這, org.springframework.aop.framework.ProxyFactoryBean 前 下一憶 回 ( 件 物 理 代 立 建 來 用 BeanFactory 是或 ApplicationContext 被 物理代立建要需而因,現實來制機理代過透是要主 S pring AOP ,節小個一 在,面介的用運可時理代定設上性屬 "proxyInterfaces" 在要您,)件 ,例實 "target" 定設上 Target 在,件物 定設上 "interceptorNames" Advice 定 有 所 上 面 介 至) (合 縫 被 會 ,時 法 方 標 目 定 指 不 在 B efore Advice W eave 。前之法方的義 :作運的 下 一 試測式 程 的 下 以 寫 撰 以 可 Before Advice BeforeAdviceDemo SpringAOPDemo.java package onlyfun.caterpillar; import org.springframework.context.ApplicationContext; import org.springframework.context. support.ClassPathXmlApplicationContext; public class SpringAOPDemo { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext( "beans-config.xml"); IHello helloProxy = (IHello) context.getBean("helloProxy"); helloProxy.hello("Justin"); } } 為 面 介 作 操 換 轉 須 必,時 件 物 理 代 的 回 取 作 操 在 得 記 IHello 來,面 介 : 果 結行執 的 式 程 個 這 下 一 看 4 21
  • 22. Spring 2.0 良信林(冊手術技 – http://openhome.cc ) 圖 4.4 BeforeAdviceDemo 果結行執的案專 與 的計設所您,到看以可中例範個這在 HelloSpeaker LogBeforeAdvice 道知用不它,說來 於對,件物的立獨個兩是 HelloSpeaker LogBeforeAdvice 在寫撰 的關相 與 何任有 沒 是 就 也 ( 在 存 的 LogBeforeAdvice API Hello- ,上之件物的它其至用運以可也 Speaker LogBeforeAdvice 而,)中 H ello- Speaker 。 計 設 的用 使 複 重 以 可 是 都 LogBeforeAdvice 與 的用 使 複 重 可 計 設 , 識 辨 的 AOP 於重著,神精的 出看以可 Aspects Advices。 件 物 的 用 使 複 重可計 設 , 識 辨 的 件 物 視 重 如 就 , OOP 將一逐是您果如 .jar 將得記,話的中之理管案專至入加案檔 spring-core.jar s pring-beans.jar s pring-context.jar spring-aop.jar 、 、 、 與 commons-logging.jar 。 入 加案 檔等 Classpath 4.2.2 After Advice After Advice 現 實 以 可 您,叫 呼 被 後 之 行 執 法 方 標 目 在 會 org.spring- ,輯邏的 framework.aop.AfterReturningAdvice作實來面介 After Advice AfterReturningAdvice :下如義定的面介 package org.springframework.aop; public interface AfterReturningAdvice extends Advice { void afterReturning(Object returnValue, Method m, 4 22
  • 23. Chapter 4 Spring AOP Object[] args, Object target) throws Throwable; } 當 ,面介 自承繼接直 AfterReturningAdvice Advice a fterReturning() ,件物標目與、數引、例實法方、值傳回的法方標目有數引的入傳中 例出丟,程流式程用應的來下接止中要若, 回傳法方 afterReturning() void 。式方的一唯是外 方 的 為,中當子例的紹介中 在以可 B efore Advice H elloSpeaker hello() 個一義定先首, 上加 , 後 之 行 執 法 AfterReturningAdvice LogAfterAdvice :面介 作實來別類 AfterReturningAdvice AfterAdviceDemo LogAfterAdvice.java package onlyfun.caterpillar; import java.lang.reflect.Method; import java.util.logging.Level; import java.util.logging.Logger; import org.springframework.aop.AfterReturningAdvice; public class LogAfterAdvice implements AfterReturningAdvice { private Logger logger = Logger.getLogger(this.getClass().getName()); public void afterReturning(Object object, Method method, Object[] args, Object target) throws Throwable { logger.log(Level.INFO, "method ends..." + method); } } 在要只著接 beans-config.xml 加增中 After Advice 在及以,例實的 的中 ProxyFactoryBean "interceptorNames" 對加增 參的 LogAfterAdvice :下 如 寫 撰 檔 義 定 , 考 4 23
  • 24. Spring 2.0 良信林(冊手術技 – http://openhome.cc ) AfterAdviceDemo beans-config.xml <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"> <bean id="logBeforeAdvice" class="onlyfun.caterpillar.LogBeforeAdvice"/> <bean id="logAfterAdvice" class="onlyfun.caterpillar.LogAfterAdvice"/> <bean id="helloSpeaker" class="onlyfun.caterpillar.HelloSpeaker"/> <bean id="helloProxy" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="proxyInterfaces" value="onlyfun.caterpillar.IHello"/> <property name="target" ref="helloSpeaker"/> <property name="interceptorNames"> <list> <value>logBeforeAdvice</value> <value>logAfterAdvice</value> </list> </property> </bean> </beans> 的定設前之了除,中義定在 LogBeforeAdvice 了入加還,外之 與式程的它其,務服誌日的 LogAfterAdvice 相案專 BeforeAdviceDemo : 示 所 下 如 面 畫考參 個 一 的 時 行 執 , 同 4 24
  • 25. Chapter 4 Spring AOP 圖 4.5 AfterAdviceDemo 果結行執的案專 個一計設以可也您 LogAspect 現實時同它讓,別類 Method- 與 BeforeAdvice 了為例範的節本,面介 AfterReturningAdvice 將而因,作實的面介調強 Advice 。計設開分 4.2.3 Around Advice 標目在何如道知經已您,中紹介的 Before Advice 與 After Advice 在 法 方在要 您 果 如 上 實 事 , 輯 邏 務 服 的 入 介後、 前 行 執 法 方 的 件 物 Advices 作實過透接直以可您,輯邏務服的 Advices 入加後前行執 org.aopalliance. ,務服 的 關 相 行 執 後 、 前行 執 法 方 於 , 面 介 intercept.MethodInterceptor 的面介 , Before Advice 與 供提別分用不而 After Advice M ethodInterceptor :下如義定 package org.aopalliance.intercept; public interface MethodInterceptor { public Object invoke( MethodInvocation methodInvocation) throws Throwable; } 是稱名件套的 到意注 MethodInterceptor org.aopalliance.intercept , 作實示表這,訂制所 由是面介個這知得以可 AOP Alliance MethodInter- 的範規 ceptor 守遵於容相以可將,別類的面介 AOP Alliance AOP 。架框 4 2
  • 26. Spring 2.0 良信林(冊手術技 – http://openhome.cc ) 在,是的同不 Before Advice及 與 After Advice MethodInterceptor 的 invoke() 用使否是定決行自要您,中法方 org.aopalliance.intercept. 會 。法方的件物標目行執來法方 MethodInvocation 的proceed() p roceed() 會機有您,前之束結 在以所,果結行執 Object 的後行執法方傳回 invoke() 正真在有只,的然當,件物的干相不全完個一另傳回是或,件物個這改修 。做麼 這 會 才 候 時 的 要 必 的前之在接直以可, 作 實何 如看 看來 際 實 MethodInterceptor AfterAdvice- Demo :寫 撰行 進 案 專 AroundAdviceDemo LogInterceptor.java package onlyfun.caterpillar; import java.util.logging.Level; import java.util.logging.Logger; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; public class LogInterceptor implements MethodInterceptor { private Logger logger = Logger.getLogger(this.getClass().getName()); public Object invoke(MethodInvocation methodInvocation) throws Throwable { logger.log(Level.INFO, "method starts..." + methodInvocation.getMethod()); Object result = null; try { result = methodInvocation.proceed(); } finally { logger.log(Level.INFO, "method ends..." + methodInvocation.getMethod() + "n"); } 4 26
  • 27. Chapter 4 Spring AOP return result; } } 個這用以可 Interceptor 的中案專 代取來 AfterAdviceDemo LogBefore- Advice 與 LogAfterAdvice :示所下如式方寫撰的檔義定 , B ean AroundAdviceDemo beans-config.xml <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"> <bean id="logInterceptor" class="onlyfun.caterpillar.LogInterceptor"/> <bean id="helloSpeaker" class="onlyfun.caterpillar.HelloSpeaker"/> <bean id="helloProxy" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="proxyInterfaces" value="onlyfun.caterpillar.IHello"/> <property name="target" ref="helloSpeaker"/> <property name="interceptorNames"> <list> <value>logInterceptor</value> </list> </property> </bean> </beans> 與果結行執 AfterAdviceDemo 圖考參以可,的樣一是果結行執的案專 4.5 。面畫的 4 27
  • 28. Spring 2.0 良信林(冊手術技 – http://openhome.cc ) Spring 入插先會,前法方個某行執正真在 Interceptor 個多有果如, Interceptor 行執後然,理處的己自行執會 I nterceptor 個每, M ethodInvocation 的 個一下有沒果如, proceed() 個一下給轉程流行執將這,法方 Interceptor Interceptor回返層一層一再,後畢完行執法方,法方的叫呼正真行執就, Interceptor 。 程 流 的 身 本式程 用 應 回 返 疊 堆 開 離 後 最 , 疊 堆 4.2.4 Throw Advice 用使以可您,事些某作件物務服些某知通時生發外例在要想若 Throws Advice 作實須必, Spring 作實要想中 在, Throws Advice org.springframe- 它,法方的何任義定有沒並面介個這而然,面介 work.aop.ThrowsAdvice 方 義 定 中 當 在 以 可 您 ,) (面 介 籤 標 個 一 是 只 T ag interface afterThrowing : 式 形 的下以 是 它 要 只 , 稱 名 法 afterThrowing([Method], [args], [target], subclassOfThrowable); 略省以可是示表等 與 、 [] 如例,定設的中 號括方Method a rgs target 是須必數參個這是就也, 是的要定一中法方,的 subclassOfThrowable 中 Throwable的 定 設 所驗檢 會 , 時 生 發 外 例 在 , 別 類 子 的 Throws Advice 法方個兩是下以,行執它知通就話的有果如,法方的型類外例合符有否是 :子例的告宣 void afterThrowing(Throwable throwable); void afterThrowing(Method method, Object[] args, Object target, Throwable throwable); 不的型類生發外例依則,態型 的同不告宣果如上法方在 Throwable 有告宣知通會 如例,法方的同不知通會,同 SomeException SomeException 。法方的 有告宣知通會 而,法方的數參 OtherException OtherException 4 28
  • 29. Chapter 4 Spring AOP 您,法 方 的 應 對 行 執 是 只 務 任 的 ,時 生 發 外 例 當 到 意 注 T hrow Advice ,後畢完行執 Throws Advice在,掉理處外例將中 在能不並 Throw Advice 的式 程 用 應 入 介 不 並 ,中之式程用應至播傳被仍外例的先原 T hrow Advice 在要 想 果 如 , 的 責 負要所 身 本 式 程 用 應 是 舊仍理 處 外 例 , 理 處 外 例 Throw 。 外 例 的 它 其 出 丟 是法作 , 程 流 理 處 的 式 程 用 應 止 中 時 理 處 Advice :面介 義定 先 首 , 子 例 際 實 的 Throws Advice 個看來 IHello ThrowAdviceDemo IHello.java package onlyfun.caterpillar; public interface IHello { public void hello(String name) throws Throwable; } 作實來別類 個一義定著接 HelloSpeaker IHello 在並,面介 hello() 方 : 出 丟 外 例 的 時 誤錯生 發 式 程 擬 模 中 當 法 ThrowAdviceDemo HelloSpeaker.java package onlyfun.caterpillar; public class HelloSpeaker implements IHello { public void hello(String name) throws Throwable { System.out.println("Hello, " + name); // 外例生發!誤錯式程!歉抱 XD throw new Exception(" 外例生發 ..."); } } 入 介 , 時 外 例 出 丟式程 用 應 在 要 需 您 果 如 服些一供提 Throw Advice 作 實 以 可 則 , 訊 資外例 些 一 錄 記 如 例 , 務 ThrowAdvice :面介 4 2
  • 30. Spring 2.0 良信林(冊手術技 – http://openhome.cc ) ThrowAdviceDemo SomeThrowAdvice.java package onlyfun.caterpillar; import java.lang.reflect.Method; import java.util.logging.Level; import java.util.logging.Logger; import org.springframework.aop.ThrowsAdvice; public class SomeThrowAdvice implements ThrowsAdvice { private Logger logger = Logger.getLogger(this.getClass().getName()); public void afterThrowing(Method method, Object[] args, Object target, Throwable subclass) { // 外例錄記 logger.log(Level.INFO, "Logging that a " + subclass + "Exception was thrown in " + method); } } 讓,義定的下以下寫中檔義定 在著接 Bean Throw Advice 生發外例在 :務服誌日供提時 ThrowAdviceDemo beans-config.xml <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"> <bean id="someThrowAdvice" class="onlyfun.caterpillar.SomeThrowAdvice"/> <bean id="helloSpeaker" class="onlyfun.caterpillar.HelloSpeaker"/> <bean id="helloProxy" 4 3
  • 31. Chapter 4 Spring AOP class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="proxyInterfaces" value="onlyfun.caterpillar.IHello"/> <property name="target" ref="helloSpeaker"/> <property name="interceptorNames"> <list> <value>someThrowAdvice</value> </list> </property> </bean> </beans> 下 一 試 測來式 程 的 下 以 寫 撰 以 可 Throw Advice :作運般期預如否是 ThrowAdviceDemo SpringAOPDemo.java package onlyfun.caterpillar; import org.springframework.context.ApplicationContext; import org.springframework.context. support.ClassPathXmlApplicationContext; public class SpringAOPDemo { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext( "beans-config.xml"); IHello helloProxy = (IHello) context.getBean("helloProxy"); try { helloProxy.hello("Justin"); } catch(Throwable throwable) { // 理處外例的式程用應 System.err.println(throwable); } } } 4 31
  • 32. 4 32 果結行執的案專 4.6 ThrowAdviceDemo 圖 :面畫 考 參 的 時 行 執 個 一 看看來,務服誌日的外額供提 T hrow Advice ,輯 邏 的 外 例 理 處 式 程 用 應 入 介不 T hrow Advice ,輯 邏 的 理 處 外 例 了 義 定 身 本 式 程 用 應,中 式 程 在 ) – http://openhome.cc 良信林(冊手術技 Spring 2.0
  • 33. Chapter 4 Spring AOP 4.3 Pointcut、Advisor 行執面介的理代至合縫接直是都 的義定所,中節小個一前在 Advice 的部細更義定以可還上實事,時生發外例中程過法方行執在者或,後、前 在。)機時用應的 ( 的趣興感了義定 P ointcut 。機時合縫 Jointpoint A dvice , 合結體具,例實 Spring 供提 用使,中 PointcutAdvisor Pointcut Advice Spring 。 的應對有都 Pointcut 的建內 PointcutAdvisor 4.3.1 NameMatchMethodPointcutAdvisor 了義定 Pointcut Jointpoint 在, Spring 用使中 PointcutAdvisor 供提來 , 合結、 Pointcut Advice P ointcutAdvisor 為 Advisor ,面介子的 A dvisor :下如義定的於面介 package org.springframework.aop; import org.aopalliance.aop.Advice; public interface Advisor { boolean isPerInstance(); Advice getAdvice(); } PointcutAdvisor 於面介 Spring :下如義定的中 package org.springframework.aop; public interface PointcutAdvisor extends Advisor { Pointcut getPointcut(); } 的建內中Spring Pointcut的應對有都 PointcutAdvisor 介 來 先 邊 這 在, 用使何如,下一紹 Spring 的供提所 org.springframework.aop.support. 4 33
  • 34. Spring 2.0 良信林(冊手術技 – http://openhome.cc ) 用, 的本基最是這, NameMatchMethodPointcutAdvisor PointcutAdvisor 定指) (式示表用使可,例 實 Spring 態靜中 Pointcut 供提以 e xpression 表 如例,定指來 用是者或,稱名法方之上標目的用應要所 Advice * hello* 的定指用應會都,時稱名法方的頭開為作 hello 以上件物理代行執示 。)法方的理代有所至用套被會 Advices ,子例的前之題主個這在( A dvice :面介的 了 義 定 您 設 假,說 來 子 例 的 際 實 個 舉 IHello NameMatchDemo IHello.java package onlyfun.caterpillar; public interface IHello { public void helloNewbie(String name); public void helloMaster(String name); } 義定著接 HelloSpeaker 作實來別類 IHello :面介 NameMatchDemo HelloSpeaker.java package onlyfun.caterpillar; public class HelloSpeaker implements IHello { public void helloNewbie(String name) { System.out.println("Hello, " + name + " newbie!"); } public void helloMaster(String name) { System.out.println("Hello, " + name + " master!"); } } 到用使會邊這如例, 的單簡 個 一 寫 撰 以 可 著 接 Advice BeforeAdvice- Demo 考參請,限有幅篇於基, LogBeforeAdvice 的中案專 4.2.1 的中 。 碼 式 程 出 列複重 再 不 邊 這 , 寫 撰 之 別 類 LogBeforeAdvice 4 34
  • 35. Chapter 4 Spring AOP 用使,檔義定 的下以寫撰著接 Bean NameMatchMethodPointcut- :起一在合結 Advisor 將並,例實 Pointcut 供提 Advice NameMatchDemo beans-config.xml <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"> <bean id="logBeforeAdvice" class="onlyfun.caterpillar.LogBeforeAdvice"/> <bean id="helloAdvisor" class="org.springframework.aop. → support.NameMatchMethodPointcutAdvisor"> <property name="mappedName" value="*Newbie"/> <property name="advice" ref="logBeforeAdvice"/> </bean> <bean id="helloSpeaker" class="onlyfun.caterpillar.HelloSpeaker"/> <bean id="helloProxy" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="proxyInterfaces" value="onlyfun.caterpillar.IHello"/> <property name="target" ref="helloSpeaker"/> <property name="interceptorNames"> <list> <value>helloAdvisor</value> </list> </property> </bean> </beans> 在 NameMatchMethodPointcutAdvisor 由,上性屬 "mappedName" 的 了定指於 "*Newbie" 行 執 以 所, 合 符 稱 名 法 方 於 由,時 法 方 helloNewbie() 4 3
  • 36. Spring 2.0 良信林(冊手術技 – http://openhome.cc ) 程的下以寫撰以可,輯邏務服的 "*Newbie" 用應會就, " logBeforeAdvice" : 期 預 合 符 否 是 果結看 看 , 試 測 行 進 來 式 NameMatchDemo SpringAOPDemo.java package onlyfun.caterpillar; import org.springframework.context.ApplicationContext; import org.springframework.context. support.ClassPathXmlApplicationContext; public class SpringAOPDemo { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext( "beans-config.xml"); IHello helloProxy = (IHello) context.getBean("helloProxy"); helloProxy.helloNewbie("Justin"); helloProxy.helloMaster("caterpillar"); } } : 示 所 下 如 面 畫考參 果 結 個 一 的 時 行 執 圖 4.7 NameMatchDemo 果結行執的案專 用使,時 義定在以可也您 Advisor 個多行進性屬 "mappedNames" Pointcut 改修可如例,義定式示表 beans-config.xml :容內的下以為 4 36
  • 37. Chapter 4 Spring AOP <beans ...> .... <bean id="helloAdvisor" class="org.springframework.aop. → support.NameMatchMethodPointcutAdvisor"> <property name="mappedNames"> <list> <value>helloNewbie</value> <value>helloMaster</value> </list> </property> <property name="advice" ref="logBeforeAdvice"/> </bean> .... </beans> 4.3.2 RegExpMethodPointcutAdvisor Spring 的供提 org.springframework.aop.support.RegexpMethod- 寫撰來 PointcutAdvisor 用使您讓以可 Regular expression Pointcut 示表 合符在,例實的 Spring 態靜中 供提以用,式 Pointcut Regular expression : 號 符 個幾的 下 以 用 使 以 可 您 , Advices 用應下況情的 4.1 RegExpMethodPointcutAdvisor 號符的用可時義定 表 號符 述描 . 元字一單何任合符 + 次多或次一元字個一前合符 * 次多或次零元字個一前合符 Escape 何任 Regular expression 號符的到用使 4 37
  • 38. Spring 2.0 良信林(冊手術技 – http://openhome.cc ) 的合 符 要 所 定 指 您 讓 性 屬 的 RegexpMethodPointcutAdvisor "pattern" 合符求要若如例,稱名法方加)稱名件套括包(稱名別類整完 :寫 撰 下 如 要 則 , 稱 名 法 方 的 始 開 的 下 onlyfun.caterpillar.IHello hello onlyfun.caterpillar.IHello.hello.* 符 定指要中式示表以所,用使 . 被經已號符 於由 Regular expression . 名 法方對 針 算 打 只 果 如 , 式 方 的 用 使 是 就 也 , ) E scape (脫跳要則,號 . :寫 撰 麼 這 以 可 則 , 稱名件 套 管 不 而 , 對 比 稱 .*hello.* 與別 類 的 用 使 所 中 案 專 用使以可 NameMatchDemo Advice一改要只, Bean :如例,了以可就檔義定 下 RegexpMatchDemo beans-config.xml <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"> <bean id="logBeforeAdvice" class="onlyfun.caterpillar.LogBeforeAdvice"/> <bean id="regExpAdvisor" class="org.springframework.aop. → support.RegexpMethodPointcutAdvisor"> <property name="pattern" value=".*Newbie"/> <property name="advice" ref="logBeforeAdvice"/> </bean> <bean id="helloSpeaker" class="onlyfun.caterpillar.HelloSpeaker"/> <bean id="helloProxy" 4 38
  • 39. Chapter 4 Spring AOP class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="proxyInterfaces" value="onlyfun.caterpillar.IHello"/> <property name="target" ref="helloSpeaker"/> <property name="interceptorNames"> <list> <value>regExpAdvisor</value> </list> </property> </bean> </beans> 用應要法方的尾結 為稱名法方合符定設,中義定的面上在 Newbie Advice 與 果 結 行 執 以 所 , 稱 名 別 類 、 件 套 的 面 前 其 論 無 且, NameMatch- Demo 。的樣一是果結行執的案專 4.3.3 ControlFlowPointcut 所 是 org.springframework.aop.support.ControlFlowPointcut Sping ,中法方某的別類定指個某,中疊堆行執的法方在斷判為用作,別類的供提 定確會才期時行執在是這於由,作動個某行執件物標目的您求要經曾否是 。能功Advices 態動的供提 是以所, Spring 入介否是 Pointcut 為別類 的中 以 NameMatchMethodPointcutAdvisor LogBeforeAdvice 要中法 方 個 某 在 否 是 , 中 別 類 在道知要想您,例 onlyfun.caterpillar.Some 入介則,話的有果如,作動些某行執件物標目的定指過求 LogBefore- Advice :寫撰下如檔義定 將以可,務服誌日供提來 Bean ControlFlowDemo beans-config.xml <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans 4 3
  • 40. Spring 2.0 良信林(冊手術技 – http://openhome.cc ) http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"> <bean id="some" class="onlyfun.caterpillar.Some"/> <bean id="logBeforeAdvice" class="onlyfun.caterpillar.LogBeforeAdvice"/> <bean id="helloFlowControlPointcut" class="org.springframework.aop.support.ControlFlowPointcut"> <constructor-arg value="onlyfun.caterpillar.Some"/> </bean> <bean id="helloAdvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor"> <property name="advice" ref="logBeforeAdvice"/> <property name="pointcut" ref="helloFlowControlPointcut"/> </bean> <bean id="helloSpeaker" class="onlyfun.caterpillar.HelloSpeaker"/> <bean id="helloProxy" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="proxyInterfaces" value="onlyfun.caterpillar.IHello"/> <property name="target" ref="helloSpeaker"/> <property name="interceptorNames"> <list> <value>helloAdvisor</value> </list> </property> </bean> </beans> ,別類 了定指,時構建 在 ControlFlowPointcut onlyfun.caterpillar.Some 是就也(件物標目的定指了求要法方個某的中別類 Some 在若示表 ( 用應則,作動些某行執)例實 "helloSpeaker" Before Advice l ogBefore- Advice :寫撰下如別類 ,務服的誌日供提) S ome 4 4
  • 41. Chapter 4 Spring AOP ControlFlowDemo Some.java package onlyfun.caterpillar; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; public class Some implements ApplicationContextAware { private IHello helloProxy; public void setApplicationContext( ApplicationContext context) throws BeansException { helloProxy = (IHello) context.getBean("helloProxy"); } public void helloEverybody() { helloProxy.helloNewbie("Justin"); helloProxy.helloMaster("caterpillar"); } public void hello() { System.out.println("Hello!"); } } 得取便方了為ApplicationContext 得 獲以 helloSpeaker ,件物理代的 Some 了現實別類 org.springframework.context.ApplicationContextAware 下一試測來式程的單簡個一寫撰以可著接,面介 ControlFlowPointcut 運的 :示所下如,作 ControlFlowDemo SpringAOPDemo.java package onlyfun.caterpillar; import org.springframework.context.ApplicationContext; import org.springframework.context. support.ClassPathXmlApplicationContext; public class SpringAOPDemo { 4 41
  • 42. Spring 2.0 良信林(冊手術技 – http://openhome.cc ) public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext( "beans-config.xml"); Some some = (Some) context.getBean("some"); if(args.length > 0 && "run".equals(args[0])) { some.helloEverybody(); } else { some.hello(); } } } 與都, 式 程 的 出 列 未 餘 其 NameMatchDemo 邊 這, 同 相 式 程 的 中 案 專 考參以可容內式程的整完,出列再不就 下一看來,案專 ControlFlowDemo 。果結的行執 訊字文的 現 出會 只 則 , 數 引 供提 有 沒 時 式 程 行 執 果 如 "run" "Hello!" 不並中疊堆行執在, Some 的例實 行執有沒為因是這,息 helloEverybody() 某行執例實 求要曾法方某的別類 :義定的定指所合符 S ome " helloSpeaker" 。作動些 的別類 行執會則,數引 了供提時式程行執果如 "run" Some 行執件物理代的 helloEverybody() 求要中法方,法方 "helloSpeaker" 因, 容 內 的 定 指 中 檔 義 定 合 符 , 法 方 helloNewbie() helloMaster() 與 Bean :示所 下 如 果 結 的 行 執 個一 , 息 訊 務 服 供 提 來 LogBeforeAdvice 用應會而 4 42
  • 43. 4 43 數引的時行執定指中 Eclipse 在 4.9 圖 :如例,數引入輸中框字文」 arguments P rogram 「在,籤 頁」 A rguments 「擇 選 後 然,令 指」 R un/Run... 「 的上單選 Eclipse 行執以可,數引的時行執定指要中 Eclipse 在 。 Pointcut 態 靜 用 使 量儘, 下 況 情 的 能 可 在 議建此 因 , 遲 延 能 效 的 倍 10 5 JDK 到 有 會 能 可 上 的同不 在 , 慢 很 會 時 行 執以所 , 行 進 期 時 行 執 在 是斷 判 的 疊 堆 行 執 於 由,出 付 的 上 能 效 於 在 是 就 題 問 的 態動 Pointcut 果結行執的案專 4.8 ControlFlowDemo 圖 Chapter 4 Spring AOP
  • 44. Spring 2.0 良信林(冊手術技 – http://openhome.cc ) 4.3.4 Pointcut 介面 的 Spring Pointcut 作實過透是 org.springframework.aop.Pointcut 面介 :下 如 義 定 其 , 現 實 來 package org.springframework.aop; public interface Pointcut { ClassFilter getClassFilter(); MethodMatcher getMethodMatcher(); Pointcut TRUE = TruePointcut.INSTANCE; } Pointcut.TRUE 是 的回傳它,作實單簡的面介 Pointcut 是 ClassFilter ClassFilter.TRUE 。 回傳 是 的回傳而, MethodMatcher MethodMatcher.TRUE ClassFilter :示所下如義定其, 用應要否是別類個一定決面介 Advice package org.springframework.aop; public interface ClassFilter { boolean matches(Class clazz); ClassFilter TRUE = TrueClassFilter.INSTANCE; } matches() ,義定的 合符是不是別類的入傳定決要中法方 Pointcut ClassFilter.TRUE總法方 的它,作實單簡的面介 ClassFilter 是 matches() 回傳是 true 這 用使以 可 則 , 稱 名 法 方 到 慮 考 只 Pointcut的立建要想果如, 。法方個 而 MethodMatcher 用應要否是法方個某 定決 Advice :示所下如義定其, package org.springframework.aop; import java.lang.reflect.Method; 4 44
  • 45. Chapter 4 Spring AOP public interface MethodMatcher { boolean matches(Method method, Class targetClass); boolean isRuntime(); boolean matches(Method method, Class targetClass, Object[] args); MethodMatcher TRUE = TrueMethodMatcher.INSTANCE; } matches() 合符否 是 法 方 個 某 的 別 類 個 某 定 決 法 方 Pointcut 兩有,義定 是像, 態 靜 於 用使本 版 個 一 第 , 本 版 個 Pointcut NameMatchMethodPoint- , 行執被 會 是 總 法 方 個 一 第 , cutAdvisor R egExpMethodPointcutAdvisor 、 個二第時此, 回傳會 Pointcut 則, isRuntime() 態靜是果如 false matches() 的本版個二第,時 為 在有只 , 行 執 被 會 不 法 方 isRuntime() true matches() 。 ControlFlowPointcut 如例,行執被會才 版個 一 第 的 它 , 作 實 單 簡 的 MethodMatcher.TRUE 是 MethodMatcher 態靜示表, 回傳是總 matches() , 回傳是總 true i sRuntime() 的本 false 出丟會就則否,法方 Pointcut 的本版個二第行執以可不以所, matches() 。外例 UnsupportedOperationException 4.3.5 Pointcut 交集、聯集操作 個幾有現發您,中之這在且並, 個多了立建果如 Pointcuts Pointcuts 現對接直以可您,時義定的 個一另為成,起一在合組以可義定的 Pointcuts ,作操的) (集聯、) Pointcuts (集交行進,件物 的在 I ntersection U nion 的 是 org.springframework.aop.support.ComposablePointcut Pointcut :作操個這成完來法方 、 的它作 操 以 可 , 別 類 作 實 intersection() u nion() ComposablePointcut intersection(ClassFilter filter); ComposablePointcut intersection(MethodMatcher mm) ComposablePointcut intersection(Pointcut other) ComposablePointcut union(ClassFilter filter) 4 4
  • 46. Spring 2.0 良信林(冊手術技 – http://openhome.cc ) ComposablePointcut union(MethodMatcher mm) :如例 Pointcut pc = new ComposablePointcut() .union(classFilter) .intersection(methodMatcher) .intersection(pointcut); 在 ComposablePointcut 個兩理 處 以 可 法 方 有 沒 中 Pointcut 您,集聯的 用使要 的 org.springframework.aop.support.Pointcuts union() :如 例,法方 Pointcut union = Pointcuts.union(pointcut1, pointcut2); 如,作操集聯或集交行進以可才寫撰接直中式程在須必是這,的然當 於 後 然 , 別 類 個 一 計設以 可 則 , 告 宣 接 直 中 檔 義 定 在 望 希 您 果 Bean Bean :如 例 , 性 用 重 的 作 操 加 增 以 可 這 , 例 實的別 類 該 告 宣 中 檔 義 定 Pointcut package onlyfun.caterpillar; import java.util.List; import org.springframework.aop.ClassFilter; import org.springframework.aop.MethodMatcher; import org.springframework.aop.Pointcut; import org.springframework.aop. framework.AopConfigException; import org.springframework.aop.support.Pointcuts; public class UnionPoint implements Pointcut { private Pointcut pointcut; public ClassFilter getClassFilter() { return getPointcut().getClassFilter(); } public MethodMatcher getMethodMatcher() { return getPointcut().getMethodMatcher(); 4 46
  • 47. Chapter 4 Spring AOP } public void setPointcuts(List pointcuts) { if(pointcuts == null || pointcuts.size == 0) { throw new AopConfigException( "個一定設要少至 Pointcut"); } pointcut = (Pointcut) pointcuts.get(0); for(int i = 0; i < pointcuts.size(); i++) { Pointcut next = (Pointcut) pointcuts.get(i); pointcut = Pointcuts.union(pointcut, next); } } private Pointcut getPointcut() { if(pointcut == null) { throw new AopConfigExeption(" 定設有沒 Pointcut"); } return pointcut; } } 4 47
  • 48. 4 48 。能功的常為以 習很是則,說來)式函(法方的作操可加增件物為態動對,員 人計設的 JavaScript 悉熟如例,員人計設的言語本腳態動悉熟 。 Introduction 現實來 framework.aop.IntroductionInterceptor org.spring-作實過透以可,中 Spring AOP 在上實事,議思可不得顯 法方的作操可加增件物為態動,說來點觀的計設別類言語式程 就 Java 。 上 之 件 物 到 法方作 操 的 外 額 些 一 加 增以可 卻 , 下 況 情 的 案 檔 別類之件物該改修不在,件物的好義定已個某讓如例,」) 法 方 的作 操 可 了加增是就說來體具(責職的件物標目了加增接直,義定為行的件物標目 了響影「它,看來度角的者用使從, Advice 的別特個是 Introduction 。 作 動 的 誌 日 些一了 加 增 乎 似 來 看 法 方 些 某 讓 如 例 , 」 為 行 的 法 方 些 某 上 件 物 標 目 了 響 影「們 它 , 看 來 度 角 的 者 用 使 從 , Throw Advice 、 A round Advice 、 A fter Advice 、 Before Advice 的過紹介前之於對 4.4.1 IntroductionInterceptor 。責職的有沒所先原) (入加態動 M ixin 件物為,為行的作操可些一了多空憑件物像好就,為行的件物個整入介接 直是而,務服入介後前法方在 等 、 Advice 像不 A fter Advice BeforeAdvice 它,看來上為行從, 的殊特種一是 Advice ,中 在 I ntroduction Spring 4.4 Introduction ) – http://openhome.cc 良信林(冊手術技 Spring 2.0
  • 49. Chapter 4 Spring AOP 與 IntroductionInterceptor 承繼 MethodInterceptor DynamicIntro- 自承繼(法方 ductionAdvice 中其,面介 implementsInterface() Dynamic- 的前目示表,話的 回傳果如) IntroductionAdvice true IntroductionInterceptor 用使要您時此,)面介的為行加增外額要是就也(面介的定規了作實 用使可不您,為行的外額行執件物標目讓,法方的上面介行執 invoke() 的有沒 來 原 上 件 物 是 的 行 執 要 為 因 , 法 方 MethodInvocation proceed() 的 proceed() 。義意有沒法方 行執,為行 假,說來子例的際實個舉,象抽較比會 Introduction 解理來上字文從 : 別 類 的 下以有 經 已 中 統 系 的 您 設 IntroductionDemo ISome.java package onlyfun.caterpillar; public interface ISome { public void doSome(); } IntroductionDemo Some.java package onlyfun.caterpillar; public class Some implements ISome { public void doSome() { System.out.println(" 。。。責職的件物來原 "); } } 的作 操 可 些 一 加 增 別 類 為 , 下 況 情 的 案檔始 原 改 修 不 在 望 希 您 Some 也的道知一唯,案檔 有只 , 有 沒 都 案 檔 碼 始原連 至 甚 您 許 也 , 法 方 .class 可別類 望 希 , 下 況 情的改 修 出 做 們 它 對 不 在 , 明 說 的 們 它 是 許 API Some doOther() 。法方 加增以 4 4
  • 50. Spring 2.0 良信林(冊手術技 – http://openhome.cc ) 作實由藉以可,中 Spring 在 IntroductionInterceptor 面上成完來面介 :面介立建法方 為先首,務任的 doOther() IntroductionDemo IOther.java package onlyfun.caterpillar; public interface IOther { public void doOther(); } 個一義定著接 OtherIntroduction 作實時同別類 IntroductionInterceptor :如例,面介 與面介 IOther IntroductionDemo OtherIntroduction.java package onlyfun.caterpillar; import org.aopalliance.intercept.MethodInvocation; import org.springframework.aop.IntroductionInterceptor; public class OtherIntroduction implements IntroductionInterceptor, IOther { // 自作實否是 IOther 面介 public boolean implementsInterface(Class clazz) { return clazz.isAssignableFrom(IOther.class); } public Object invoke(MethodInvocation methodInvocation) throws Throwable { // 自來法方的行執果如 IOther 義定的面介 if(implementsInterface( methodInvocation.getMethod().getDeclaringClass())) { // (入加外額行執 mixin為行的) return methodInvocation.getMethod(). invoke(this, methodInvocation.getArguments()); } else { return methodInvocation.proceed(); 4
  • 51. Chapter 4 Spring AOP } } public void doOther() { System.out.println(" 。。。責職的加增 "); } } 在要著接 Bean 將中檔義定 Introduction 至合縫 Some 用 使, 上 之 件 物 org.springframework.aop.support.DefaultIntroductionAdvisor 以可就 :如例,了 IntroductionDemo beans-config.xml <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"> <bean id="some" class="onlyfun.caterpillar.Some"/> <bean id="otherIntroduction" class="onlyfun.caterpillar.OtherIntroduction"/> <bean id="otherAdvisor" class="org.springframework.aop. → support.DefaultIntroductionAdvisor"> <constructor-arg ref="otherIntroduction"/> <constructor-arg value="onlyfun.caterpillar.IOther"/> </bean> <bean id="proxyFactoryBean" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="proxyInterfaces" value="onlyfun.caterpillar.ISome"/> <property name="target" ref="some"/> <property name="interceptorNames"> 4 1
  • 52. Spring 2.0 良信林(冊手術技 – http://openhome.cc ) <list> <value>otherAdvisor</value> </list> </property> </bean> </beans> 它給要需,時構建在 DefaultIntroductionAdvisor IntroductionInterceptor 測式程的單簡個一寫撰來,在現,面介的為行外額理代要所及以,例實的 :為 行 加 增 外 額 件 物 為謂何 解 了 步 一 進 更 以 可,中 當 式 程 個 這 從 , 試 IntroductionDemo SpringAOPDemo.java package onlyfun.caterpillar; import org.springframework.context.ApplicationContext; import org.springframework.context. support.ClassPathXmlApplicationContext; public class SpringAOPDemo { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext( "beans-config.xml"); ISome some = (ISome) context.getBean("proxyFactoryBean"); some.doSome(); //像好來看 some 責職了加增態動件物 ((IOther) some).doOther(); } } 4 2
  • 53. Chapter 4 Spring AOP 有會不並先原它,說來件物的考參所 於對 some doOther()操供可法方 在現,制機 Spring AOP的 過透而然,作 Introduction some 件物的考參所 : 果 結 的 行 執下一 看 來 以 可 , 作 操 以 可 法 方 doOther() 了多 圖 4.10 IntroductionDemo 果結行執的案專 4.4.2 DelegatingIntroductionInterceptor org.springframework.aop.support.DelegatingIntroductionInterceptor 可您, 別 類 作 實 的 供 提 所 面 介 Spring AOP 為中 IntroductionInterceptor 是 件物有帶以可並,為行的加增件物標目為望希加添,別類個這承繼接直以 ,態狀的定鎖」否「、」是「有帶攜件物讓如例,態狀的己自 D elegating- 。 節細的 份 部 大 了 作 實 經 已 IntroductionInterceptor :別類 的 樣 這 有 經 已 中 統系設 假 , 說 來 子 例 個 舉 DelegatingIntroductionDemo ISome.java package onlyfun.caterpillar; public interface ISome { public void setSome(String some); public String getSome(); } 4 3
  • 54. Spring 2.0 良信林(冊手術技 – http://openhome.cc ) DelegatingIntroductionDemo Some.java package onlyfun.caterpillar; public class Some implements ISome { private String some; public void setSome(String some) { this.some = some; } public String getSome() { return some; } } 個 一 加 增 以 可 望希您 , 下 況 情 的 容 內 式 程 Some.java 改修不在 locked 定設來法方 boolean 與 的作操可加增並,員成料資態型 lock() 的 unlock() 定 鎖 則, 為 定 設 被 locked true false 果 如, 或 為 員 成 locked true setSome() 。) ( 動變可 不 為 定 鎖 件 物 將 是就也 , 行 執 被 法 無 法 方 I mmutable 的件物標目至加添想是的義定面上,面介 ILockable 個一義定先以可 :法方作操 DelegatingIntroductionDemo ILockable.java package onlyfun.caterpillar; public interface ILockable { public void lock(); public void unlock(); public boolean isLocked(); } 承繼 著接 DelegatingIntroductionInterceptor 作實時同並,別類 ILockable :面介 4 4