Spring支持的AspectJ切入点指示词:
execution:匹配一个方法的执行,最常用的一个;
within:匹配在一个包或者类型中;
this:匹配一个这个类型的proxy;
target:匹配一个这个类型的目标对象--被代理的对象;
args:匹配一个方法,参数是这个类型;
组合切入点:
@Pointcut("execution(public * *(..))")
private void anyPublicOperation() {}
@Pointcut("within(com.xyz.someapp.trading..*)")
private void inTrading() {}
@Pointcut("anyPublicOperation() && inTrading()")
private void tradingOperation() {}
第一个切入点的定义用到了execution,指任何public的方法的执行;第二个切入点的定义用到了within,指在指定的包内;第三个切入点的定义则组合了两者,指在特定包中的任何public方法。
within(com.xyz.service.*)
within(com.xyz.service..*)
这两个within的区别在于,第二个包含了service这个包的子包,而第一个只是service这个包下面的所有类的意思。
this(com.xyz.service.AccountService)
指代任何继承了AccountService这个接口的proxy;
target(com.xyz.service.AccountService)
指代任何继承了AccountService这个接口的目标类;
args(java.io.Serializable)
任何以实现了Serializable接口的类为参数的切入点;
@target(org.springframework.transaction.annotation.Transactional)
目标对象有@Transactional的任何切入点;
@within(org.springframework.transaction.annotation.Transactional)
目标对象的声明类型中有@Transactional的任何切入点;
@annotation(org.springframework.transaction.annotation.Transactional)
执行的方法有@Transactional定义的任何切入点;
@args(com.xyz.security.Classified)
切入点只有一个参数,而且参数的类型有@Classified注解;
bean(tradeService)
任何定义在tradeService这个Bean中的切入点;
bean(*Service)
同上,只是bean的名字使用了通配符;
在切面中访问目标对象/目标方法的参数,返回值等:
@AfterReturning(
pointcut="com.xyz.myapp.SystemArchitecture.dataAccessOperation()",
returning="retVal")
public void doAccessCheck(Object retVal) {
// ...
}
@AfterThrowing(
pointcut="com.xyz.myapp.SystemArchitecture.dataAccessOperation()",
throwing="ex")
public void doRecoveryActions(DataAccessException ex) {
// ...
}
以上第一个例子访问目标方法的返回值,第二个方法访问发生的异常。
@Around("com.xyz.myapp.SystemArchitecture.businessService()")
public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable {
// start stopwatch
Object retVal = pjp.proceed();
// stop stopwatch
return retVal;
}
使用ProceedingJoinPoint这个类可以获得目标方法的返回值,还可以获得目标对象:
Object target = pjp.getTarget();
或者目标方法的签名等:
String methodName = pjp.getSignature().getName();
org.aspectj.lang.JoinPoint类除了不能proceeding外其他功能和ProceedingJoinPoint相同;
@Before("com.xyz.myapp.SystemArchitecture.dataAccessOperation() && args(account,..)")
public void validateAccount(Account account) {
// ...
}
也可以这样访问目标对象的参数。@Before("com.xyz.lib.Pointcuts.anyPublicMethod() && @annotation(auditable)")
public void audit(Auditable auditable) {
AuditCode code = auditable.value();
// ...
}
访问目标方法的注解。
具体实例可参见本系列的第二篇和第四篇。