AOP之AspectJ
AspectJ也是一个实现了AOP思想的项目,它是基于编译期来实现的,而Spring AOP是基于动态代理来实现的,只不过Spring AOP中使用了AspectJ所定义的几个注解,但是注解背后的实现原理是不一样的,一个是编辑期,一个是动态代理。
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.9.5</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.5</version>
</dependency>
@Before
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
@Aspect
public class LoggingAspect {
@Before("execution(* com.example.service.*.*(..))")
public void logBefore(JoinPoint joinPoint) {
System.out.println("Before executing " + joinPoint.getSignature());
}
}
上述代码中,定义了一个名为LoggingAspect的切面,使用@Before注解表示该方法是一个前置通知,在切入点表达式execution(* com.example.service.*.*(..))中,使用通配符*表示任意返回类型、任意类、任意方法名,括号内的..表示任意参数个数和类型。
当应用程序中被切入点表达式匹配到的任何一个方法被调用时,LoggingAspect中的logBefore方法都会被执行,并在控制台输出相应的日志信息。
@AfterReturning
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
@Aspect
public class LoggingAspect {
@AfterReturning(pointcut = "execution(* com.example.service.*.*(..))", returning = "result")
public void logAfterReturning(JoinPoint joinPoint, Object result) {
System.out.println("After executing " + joinPoint.getSignature() + ", result: " + result);
}
}
上述代码中,定义了一个名为LoggingAspect的切面,使用@AfterReturning注解表示该方法是一个后置通知,pointcut属性表示切入点表达式,returning属性表示方法返回值绑定到result参数上。
当匹配到的方法正常返回时,LoggingAspect中的logAfterReturning方法会被执行,并在控制台输出相应的日志信息,包括返回值。
@AfterThrowing
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
@Aspect
public class LoggingAspect {
@AfterThrowing(pointcut = "execution(* com.example.service.*.*(..))", throwing = "exception")
public void logAfterThrowing(JoinPoint joinPoint, Throwable exception) {
System.out.println("Exception occurred in " + joinPoint.getSignature() + ", exception: " + exception);
}
}
上述代码中,定义了一个名为LoggingAspect的切面,使用@AfterThrowing注解表示该方法是一个异常通知,pointcut属性表示切入点表达式,throwing属性表示抛出的异常绑定到exception参数上。
当匹配到的方法抛出异常时,LoggingAspect中的logAfterThrowing方法会被执行,并在控制台输出相应的日志信息,包括异常信息。
@After
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
@Aspect
public class LoggingAspect {
@After("execution(* com.example.service.*.*(..))")
public void logAfter(JoinPoint joinPoint) {
System.out.println("After executing " + joinPoint.getSignature());
}
}
上述代码中,定义了一个名为LoggingAspect的切面,使用@After注解表示该方法是一个最终通知,pointcut属性表示切入点表达式。
当匹配到的方法执行完成后,LoggingAspect中的logAfter方法会被执行,并在控制台输出相应的日志信息。
@Around
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
@Aspect
public class LoggingAspect {
@Around("execution(* com.example.service.*.*(..))")
public Object logAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("Before executing " + proceedingJoinPoint.getSignature());
Object result = null;
try {
result = proceedingJoinPoint.proceed();
} catch (Throwable e) {
System.out.println("Exception occurred in " + proceedingJoinPoint.getSignature() + ", exception: " + e);
throw e;
}
System.out.println("After executing " + proceedingJoinPoint.getSignature() + ",result: " + result);
}
}
