【轉】AOP實現(三)——Spring 2.0中Pointcut的定義
關鍵字: Pointcut的定義在 Spring 2.0 中, Pointcut 的定義包括兩個部分: Pointcut 表示式 (expression) 和 Pointcut 簽名 (signature) 。讓我們先看看 execution 表示式的格式:
java 代碼
- execution(modifier-pattern?
- ????????? ret-type-pattern
- ????????? declaring-type-pattern?
- ????????? name-pattern(param-pattern)
- ????????? throws-pattern?)
括號中各個 pattern 分別表示修飾符匹配( modifier-pattern? )、返回值匹配( ret-type-pattern )、類路徑匹配( declaring-type-pattern? )、方法名匹配( name-pattern )、參數匹配( (param-pattern) )、異常類型匹配( throws-pattern? ),其中后面跟著“ ? ”的是可選項。
在各個 pattern 中可以使用“ * ”來表示匹配所有。在 (param-pattern) 中,可以指定具體的參數類型,多個參數間用“ , ”隔開,各個也可以用“ * ”來表示匹配任意類型的參數,如 (String) 表示匹配一個 String 參數的方法; (*,String) 表示匹配有兩個參數的方法,第一個參數可以是任意類型,而第二個參數是 String 類型;可以用 (..) 表示零個或多個任意參數。
現在來看看幾個例子:
1 ) execution(* *(..))
表示匹配所有方法
2 ) execution(public * com. savage.service.UserService.*(..))
表示匹配 com.savage.server.UserService 中所有的公有方法
3 ) execution(* com.savage.server..*.*(..))
表示匹配 com.savage.server 包及其子包下的所有方法
除了 execution 表示式外,還有 within 、 this 、 target 、 args 等 Pointcut 表示式。 一個 Pointcut 定義由 Pointcut 表示式和 Pointcut 簽名組成,例如:
java 代碼
- //Pointcut表示式
- @Pointcut("execution(* com.savage.aop.MessageSender.*(..))")
- //Point簽名
- privatevoid log(){}?????????????????????????????
然后要使用所定義的 Pointcut 時,可以指定 Pointcut 簽名,如
java 代碼
- @Before("og()")
上面的定義等同與:
java 代碼
- @Before ( "execution(* com.savage.aop.MessageSender.*(..))" )
Pointcut 定義時,還可以使用 && 、 || 、 ! 運算,如:
java 代碼
- @Pointcut("execution(* com.savage.aop.MessageSender.*(..))")
- privatevoid logSender(){}
- @Pointcut("execution(* com.savage.aop.MessageReceiver.*(..))")
- privatevoid logReceiver(){}
- @Pointcut("logSender() || logReceiver()")
- privatevoid logMessage(){}
這個例子中, logMessage() 將匹配任何 MessageSender 和 MessageReceiver 中的任何方法。
還可以將一些公用的 Pointcut 放到一個類中,以供整個應用程序使用,如:
java 代碼
- package com.savage.aop;
- import org.aspectj.lang.annotation.*;
- publicclass Pointcuts {
- ?? @Pointcut("execution(* *Message(..))")
- ?? publicvoid logMessage(){}
- ?? @Pointcut("execution(* *Attachment(..))")
- ?? publicvoid logAttachment(){}
- ?? @Pointcut("execution(* *Service.*(..))")
- ?? publicvoid auth(){}
- }
在使用這些 Pointcut 時,指定完整的類名加上 Pointcut 簽名就可以了,如:
java 代碼
- package com.savage.aop;
- import org.aspectj.lang.JoinPoint;
- import org.aspectj.lang.annotation.*;
- @Aspect
- publicclass LogBeforeAdvice {
- ?? @Before("com.sagage.aop.Pointcuts.logMessage()")
- ?? publicvoid before(JoinPoint joinPoint) {
- ????? System.out.println("Logging before " + joinPoint.getSignature().getName());
- ?? }
- }
當基于 XML Sechma 實現 Advice 時,如果 Pointcut 需要被重用,可以使用
xml 代碼
- <aop:config>??
- ????<aop:pointcut?id="log"???
- ??????????expression="execution(*?com.savage.simplespring.bean.MessageSender.*(..))"/>??
- ????<aop:aspect?id="logging"?ref="logBeforeAdvice">??
- ????????<aop:before?pointcut-ref="log"?method="before"/>??
- ????????<aop:after-returning?pointcut-ref="log"?method="afterReturning"/>??
- ????</aop:aspect>??
- </aop:config>??