一、简介
AspectJ是一个面向切面的框架,它扩展了Java语言。AspectJ定义了AOP语法,它有一个专门的编译器用来生成遵守Java字节编码规范的Class文件。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
二、语法
- *:匹配任意数量的字符
- +:匹配指定的类及其子类
- ..:匹配任意层级的包或任意数量的入参
- &&:多个切点条件同时成立
- ||:多个切点条件任意成立
execution(
modifier-pattern -> 修饰符(public、protected、private)
return-type-pattern -> 返回类型(必填)
declaring-type-pattern -> 包或类
name-pattern(param-pattern) -> 方法名以及入参(必填)
throws-pattern -> 抛出异常
三、切面和切点
定义切点:@Pointcut(value = "..."),方法级别的注解
- execution(public * com.wjx..*(..)),指定包下的所有方法创建切点
- @annotation(java.lang.annotation.*),被指定包下的注解标注时创建切点
- within(com..UserServiceImpl),指定类下的方法创建切点
- args(Integer,..),第一个入参是Integer类型的方法创建切点
- @args(org.springframework.web.bind.annotation.RequestParam),指定方法入参有目标注解时创建切点
- this(com..UserServiceImpl),AOP代理对象的方法创建切点
- target(com..UserServiceImpl),目标对象的方法创建切点
- @target(org.springframework.transaction.annotation.Transactional),指定类上有目标注解时创建切点
- bean(*Service),指定id或name结尾的bean对象的方法创建切点
四、通知
- 前置通知(@Before):在切点前执行通知
- 后置通知(@After):在切点后执行通知
- 返回型后置通知(@AfterReturning):在带有返回值的切点后执行通知
- 异常型后置通知(@AfterThrowing):在切点抛出异常后执行通知
- 环绕通知(@Around):在切点执行的任意时刻都执行通知
@Aspect
@Component
public class HttpAspect {
private Logger mLogger = LoggerFactory.getLogger(HttpAspect.class);
@Before(value = "cut()")
public void before(JoinPoint point) {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
mLogger.error("url={}", request.getRequestURL());
mLogger.error("method={}", request.getMethod());
mLogger.error("ip={}", request.getRemoteAddr());
mLogger.error("class_method={}", point.getSignature().getDeclaringTypeName() + "." + point.getSignature().getName());
mLogger.error("args={}", point.getArgs());
mLogger.error("前置通知");
}
@After("cut()")
public void after(JoinPoint point) {
mLogger.error("后置通知");
}
@AfterReturning(pointcut = "cut()", returning = "object")
public void returning(Object object) {
mLogger.error("return={}", object);
mLogger.error("返回型后置通知");
}
@AfterThrowing(pointcut = "cut()",throwing ="throwable")
public void throwing(Throwable throwable){
mLogger.error("异常型后置通知"+throwable);
}
@Around(value = "cut()")
public void around(ProceedingJoinPoint joinPoint){
mLogger.error("method={}",joinPoint.getSignature().getName());
mLogger.error("target={}",joinPoint.getTarget());
mLogger.error("args={}",joinPoint.getArgs());
mLogger.error("环绕通知");
}
@Pointcut(value = "execution(public * com..*(..))")
public void cut() {
mLogger.error("切点");
}
}
网友评论