天天看點

【轉】pointcut的定義和說明

在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>