隨筆-193  評論-715  文章-1  trackbacks-0

          相信知道Spring的朋友都知道兩個名詞:IOC和AOP,對於Spring的IOC和AOP並不是本文所討論的范圍,IOC是十分好理解的,也是相對簡單的技朮,只要不是JAVA的初學者,我想大都能理解,網上也有較多的關於此理論的闡述。之於Spring的AOP,在我的Blog之前的文章中也有總結,見《Spring AOP Review》(http://www.aygfsteel.com/fastzch/archive/2006/08/15/63616.html)。

          AOP之於IOC則要相對較為復雜一些,但是我們可以通過下面這個實際項目中的例子來看看AOP的威力。項目中常常都會有這樣的情況,每個業務處理的方法在進入和退出時都需要記錄Debug信息,表示正常進入和退出此方法。而我們一般的做法是在每個類的每個方法中都例用LOG4J的功能在此處打印一條LOG信息,而如果我們采用AOP的思想,則可以給所有這些方法做兩個切面,在所有這些方法執行前和執行後均記錄LOG信息。

          我們可以試想一下,如果我們的項目有2000個類,每個文件平均8個方法,每個類得定義一個LOG變量,每條LOG記錄至少3行代碼,如:
          if(DEBUGLOG.isDebugEnable()){
          ?DEBUGLOG.debug("*** class *** method begin.");
          }

          那麼總共需要2000*8*3*2+2000*1=98000行代碼來完成此功能,而如果我們采用AOP的思想可能僅僅需要上百行代碼足矣。這樣,我們不僅可以減少工作量,同時也可以減少出錯的機會,讓程序員更好的關注業務邏輯的處理。

          好了,小小的功能便見識了其威力,再說多了有幫忙AOP打Ad.的嫌疑,書歸正傳。

          對於AOP的基礎知識不想在此浪費精力,大多人都了解PointCut,Advice,aspect等概念在網上有太多的資料。

          AspectJ的入門也不再冗述,安裝過Eclipse的AspectJ插件後便會有教程,同時大家也可以去看這篇文章:AspectJ初探(http://www.aygfsteel.com/pesome/archive/2005/08/03/9148.html)。

          PointCut定義的格式如下:
          pointcut name([parameters]):designator(ajoinpoint);

          AspectJ有以下幾種連接點:
          方法調用:pointcut name():call(public void method());
          方法調用執行:pointcut name():execution(public void method());
          構造方法調用:pointcut name():initialization(Object.new());
          構造方法調用執行:pointcut name():execution(public Object.new());
          字段獲取:pointcut name():get(public String Object.field);
          字段設置:pointcut name():set(public String Object.field);
          異常處理程序執行:pointcut name():throws(Exception());
          類初始化:
          對象初始化:
          注意:如果同時給某一個切面應用方法調用和方法調用執行兩種連接點時,方法調用在方法調用執行之前執行。

          AspectJ連接點簽名方式:
          方法調用執行:<access_type><return_value><type>.<method_name>(parameter_list)
          構造方法調用執行:<method_access_type><class_type.new>(<parameter_list>)[throws <exception>]
          字段獲取:<field_type><class_type>.<field_name>
          字段設置:<field_type><class_type>.<field_name>
          注意:如果字段是數組或是集合等類型時,並不是對數組每個單元的寫入就觸發連接點,而是只有當一個值分配給變量的時候才會觸發連接點。
          異常處理程序執行:<exception type>
          類/對象初始化:<method_access_type><method_name>(<parameter_list>)

          類型名稱模式匹配:
          *是一種能夠用來匹配所有類型的特定類型名稱。另外,*能夠匹配除“.”以外的零或多個符號。
          所有的類的所有方法(有且僅有一個參數的方法)用下面這樣的模式來匹配:
          call(* * *.*(*))
          注意,這個模式只匹配帶有一個參數的方法,AspectJ中還有另外一個可用的通配符可以用來匹配任何字符序列,即“..”。那麼,

          匹配所有類的所有方法的模式為:
          call(* * *.*(..))
          當一個類是執行階段中的目標的時候,pointcut賦值符調用目標將被觸發。這個時候連接點需要基於包中的具體類來定義。如:
          target(com.test.ClassA)
          如果要匹配com.test路徑下的任何類為目標,那麼可以使用下面的簽名:
          target(com.test..*)
          如果要匹配內部類的類型,需要使用通配符“..”,如下:
          target(com.test.*.*.*.*)
          內部類還可以是方法調用連接點簽名的一部分,如下:
          call(private * com.test..*(..))

          子類型模式:即匹配某一個類的所有子類,用“+”。如:
          call (ObjectName+.new(..))
          拋出模式:
          call(* * *.*(..) throws * Exception *)
          利用!可以否定某一異常匹配,如:call(* * *.*(..) throws ! BusiException)

          前面所有定義的連接點都可以用邏輯操作符and(&&)、or(||)和not(!)組合起來。如:我們對A類層次中的子類型而不是A類本身感興趣,為了只匹配子類型中的構造函數,可以使用下面的連接點:
          call((A+ && !A).new(..))

          反射:
          thisJoinPoint--該變量被綁定到連接點對象,並且有父類型org.aspectj.lang.JoinPoint。
          其有效的方法如下:
          String toString();--該方法返回連接點的一個字符串表示,一般為連接點的方法簽名。
          String toShortString();--該方法返回連接點的一個短字符串表示,一般為帶類名的方法名。
          String toLongString();--該方法返回連接點的一個擴展表示,一般為連接點的完整的方法簽名。
          以下是我的樣例打印出來的結果:
          ??????toString():call(void test.Hello.sayHello(String))
          ??????toShortString():call(Hello.sayHello(..))
          ??????toLongString():call(public void test.Hello.sayHello(java.lang.String))
          Object getThis();--該方法返回與該連接點關聯的當前正在執行的對象。此方法只有在連接點是調用執行(execution)時才能得到該對象,如果在連接點是調用(call)的時候,得到的對象是null。
          Object getTarget();--該方法返回與連接點關聯的目標對象。目標對象在方法調用接收或構造方法調用接收的連接點上有效。
          Object[] getArgs();--該方法將實際參數返回到邊接點上。
          Signature getSignature();--該方法返回表示連接點簽名的對象。Signature對象包含幾個自身的方法:
          ??????String getName();該方法返回簽名的標識符部分。
          ??????int getModifiers();該方法返回以整數表示的簽名的修飾符。其整數可以轉換成java.lang.reflect.Modifier類型,用來確定連接點所使用的訪問修飾符的類型。
          SourceLocation getSourceLocation();--該方法與thisJointPoint對象關聯,從表示連接點調用程序的SourceLocation類返回一個對象。如果沒有對象,則返回空。
          String getKind();--該方法返回表示已觸發連接點類型的字符串。
          StaticPart getStaticPart();--該方法返回上下文的靜態部分。

          thisJoinPointStaticPart--該變量僅被綁定到有限的連接點對象,在使用的時候不需要分配內存。
          靜態部分可用的方法如下:
          Signature getSignature();
          SourceLocation getSourceLocation();
          String getKind();
          String toString();
          String toShortString();
          String toLongString();
          這些方法同thisJoinPoint部分所列相同。

          thisEnclosingJoinPointStaticPart--該變量僅被綁定到連接點對象的靜態部分,並且有父類型org.aspectj.lang.JoinPoint.StaticPart。

          posted on 2006-12-11 21:18 Robin's Programming World 閱讀(2432) 評論(1)  編輯  收藏 所屬分類: Java

          評論:
          # re: AspectJ各種連接點定義及反射 2008-07-30 01:20 | zxcz
          <a href="http://www.ionpromotion.jp">アダルトサイト</a> ... 5.その肝心のア<a href="http://www.ionpromotion.jp/top/index.html">アダルトサイト</a> ... (最悪の場合、相手側に電話番號が漏れます)。「警察に訴えるぞ」とこちらが言っても、「あなたはアダル<a href="http://www.t-powers.tv/index.html">アダルト</a>を利用したことが一度もないのですか?」と言い返されたらどうしますか? ...
          総合アダルト検索サイト、抜天市場、かってないス人気サイトを瞬時に検索新総合エンターテイメントサイトです! 當ホームページは、18歳未満の視聴が禁止されているアダルトサイトです。 畫像や表現など青少年には相応しくないと思われますので直ちにお引取りください。 アダルトアニメ、コミック(254) アダルトサイト閲覧に関するアドバイス(4) アダルトブログ(207) 畫像(53) 官能小説(57) ゲーム(117) 告白(16) <a href="http://www.hilive.tv/girls.aspx">av</a>(6) 性行動の種類(205) 性(202) 動畫(8) ビデオ、映畫(34) ...
            回復  更多評論
            
          主站蜘蛛池模板: 饶平县| 沾益县| 永丰县| 革吉县| 四平市| 弋阳县| 察雅县| 正安县| 民丰县| 陆良县| 武鸣县| 北流市| 焦作市| 依安县| 达尔| 保靖县| 嘉定区| 高淳县| 腾冲县| 松溪县| 黑水县| 桦川县| 剑川县| 白城市| 临朐县| 临汾市| 昆山市| 陆河县| 澄江县| 乃东县| 东丽区| 化德县| 昆山市| 双辽市| 寿阳县| 麻阳| 宝鸡市| 白水县| 昭平县| 衡阳县| 随州市|