Spring 中 AOP 使用
Contents
开启
@Configuration
@EnableAspectJAutoProxy
public class AppConfig {
}
或xml中配置
<aop:aspectj-autoproxy/>
声明一个 Aspect
@Aspect
@Component
public class NotVeryUsefulAspect {
}
声明一个切点
@Pointcut("execution(* transfer(..))")// the pointcut expression
private void anyOldTransfer() {}// the pointcut signature
支持的切点类型
- execution
- within
- this
- target
- args
- @target
- @args
- @within
- @annotation
组合切点
@Pointcut("execution(public * *(..))")
private void anyPublicOperation() {}
@Pointcut("within(com.xyz.someapp.trading..*)")
private void inTrading() {}
@Pointcut("anyPublicOperation() && inTrading()")
private void tradingOperation() {}
增强
Before
@Aspect
public class BeforeExample {
@Before("com.xyz.myapp.SystemArchitecture.dataAccessOperation()")
public void doAccessCheck() {
// ...
}
}
AfterReturning
@AfterReturning("com.xyz.myapp.SystemArchitecture.dataAccessOperation()")
public void doAccessCheck() {
// ...
}
获取返回的对象
@AfterReturning(
pointcut="com.xyz.myapp.SystemArchitecture.dataAccessOperation()",
returning="retVal")
public void doAccessCheck(Object retVal) {
// ...
}
AfterThrowing
@AfterThrowing("com.xyz.myapp.SystemArchitecture.dataAccessOperation()")
public void doRecoveryActions() {
// ...
}
@AfterThrowing(
pointcut="com.xyz.myapp.SystemArchitecture.dataAccessOperation()",
throwing="ex")
public void doRecoveryActions(DataAccessException ex) {
// ...
}
After
@After("com.xyz.myapp.SystemArchitecture.dataAccessOperation()")
public void doReleaseLock() {
// ...
}
Around
@Around("com.xyz.myapp.SystemArchitecture.businessService()")
public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable {
// start stopwatch
Object retVal = pjp.proceed();
// stop stopwatch
return retVal;
}
例子
package com.example.value.demo;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import java.util.Arrays;
@Aspect
@Component
public class LogAspectJ {
@Pointcut("execution(* com.example.value.demo.HelloService*.*(..))")
public void publicPoint() {
}
@Around("publicPoint()")
public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable {
// start stopwatch
System.out.println("调用方法 : " + pjp.getSignature().toLongString());
System.out.println("方法参数 : " + Arrays.toString(pjp.getArgs()));
Object retVal = pjp.proceed();
// stop stopwatch
System.out.println("方法返回 : " + retVal);
return retVal;
}
}
也可以加上人方法调用前和调用后的时间, 然后就可以统计该方法的执行时间了~