在Spring 2.0中,Pointcut的定義包括兩個部分:Pointcut表示式(expression)和Pointcut簽名(signature)。讓我們先看看execution表示式的格式:
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簽名組成,例如:
//Pointcut表示式
@Pointcut("execution(* com.savage.aop.MessageSender.*(..))")
//Point簽名
private void log(){}
然後要使用所定義的Pointcut時,可以指定Pointcut簽名,如
@Before("og()")
上面的定義等同與:
@Before("execution(* com.savage.aop.MessageSender.*(..))")
Pointcut定義時,還可以使用&&、||、!運算,如:
@Pointcut("execution(* com.savage.aop.MessageSender.*(..))")
private void logSender(){}
@Pointcut("execution(* com.savage.aop.MessageReceiver.*(..))")
private void logReceiver(){}
@Pointcut("logSender() || logReceiver()")
private void logMessage(){}
這個例子中,logMessage()将比對任何MessageSender和MessageReceiver中的任何方法。
還可以将一些公用的Pointcut放到一個類中,以供整個應用程式使用,如:
package com.savage.aop;
import org.aspectj.lang.annotation.*;
public class Pointcuts {
@Pointcut("execution(* *Message(..))")
public void logMessage(){}
@Pointcut("execution(* *Attachment(..))")
public void logAttachment(){}
@Pointcut("execution(* *Service.*(..))")
public void auth(){}
}
在使用這些Pointcut時,指定完整的類名加上Pointcut簽名就可以了,如:
package com.savage.aop;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
@Aspect
public class LogBeforeAdvice {
@Before("com.sagage.aop.Pointcuts.logMessage()")
public void before(JoinPoint joinPoint) {
System.out.println("Logging before " + joinPoint.getSignature().getName());
}
}
當基于XML Sechma實作Advice時,如果Pointcut需要被重用,可以使用<aop:pointcut></aop:pointcut>來聲明Pointcut,然後在需要使用這個Pointcut的地方,用pointcut-ref引用就行了,如:<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>