目标bean
package com.example.service;
import org.springframework.stereotype.Component;
@Component
public class UserService {
public String sayHello() {
return "Hello!";
}
}
示例1
// 自定义注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface LogExecution {
}
// 切面
@Aspect
@Order(100)
public class AnnotationAspect {
// 切点表达式没有抽出来
@Before("@annotation(LogExecution)")
public void logBeforeAnnotatedMethod() {
System.out.println("Executing annotated method...");
}
}
示例2
@Aspect
@Order(10)
public class LoggingAspect {
// 定义切点
@Pointcut("execution(* com.example.service.*.*(..))")
public void serviceMethods() {
}
/**
* 前置通知,参数表示连接点,可以获取方法,参数信息,是可选的
*/
@Before("serviceMethods()")
public void logBefore(JoinPoint joinPoint) {
// 获取方法名称
String methodName = joinPoint.getSignature().getName();
// 获取方法参数
Object[] methodArgs = joinPoint.getArgs();
System.out.println("前置通知:方法 " + methodName + " 开始执行");
}
/**
* 后置通知,不管方法是否发生异常都会通知
*/
@After("serviceMethods()")
public void logAfter(JoinPoint joinPoint) {
String methodName = joinPoint.getSignature().getName();
System.out.println("前置通知:方法 " + methodName + " 执行结束");
}
/**
* 返回通知,发生异常不会通知,如果要获取结果要通过 returning 指定接收结果的参数名称
*/
@AfterReturning(pointcut = "serviceMethods()", returning = "result")
public void logAfterReturning(Object result) {
String methodName = joinPoint.getSignature().getName();
System.out.println("返回通知:方法 " + methodName + " 正常执行完毕,结果为:" + result);
}
/**
* 异常通知,当目标方法发生异常时通知,如果要知道是什么异常,也要指定接收异常的参数名称,通过 throwing 来指定
*/
@AfterThrowing(pointcut = "serviceMethods()", throwing = "ex")
public void logAfterThrowing(Throwable ex) {
System.out.println("异常通知:方法 " + methodName + " 发生异常,异常为:" + ex);
}
}
示例3
/**
* 环绕通知,四合一通知
* ProceedingJoinPoint 是 JoinPoint 子接口,扩展了执行目标方法的能力
* 如果发生异常要跑出去,因为可能是多层代理,发生异常不抛出去的话,上层代理不知道发生了异常,就会拿到返回值是 null 做后续处理
*/
@Around("serviceMethods()")
public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("Before..."); // 前置通知通知
Object result = null;
try {
result = joinPoint.proceed(); // 执行目标方法
System.out.println("AfterReturning"); // 没发生异常,可以做返回通知
} catch (Exception e) {
System.out.println("AfterThrowing..."); // 发生异常,可以做异常通知
throw e; // 抛出异常
} finally {
System.out.println("After..."); // 后置通知
}
return result;
}