Spring中的aspectj注解AOP

Spring中的aspectj注解AOP

常用的有

  • After
  • AfterReturning
  • AfterThrowing
  • Around
  • Aspect
  • Before

注解的执行

没有异常的执行顺序

1
around begin ->  before -> afterReturning -> after -> around end

抛出异常的执行顺序

1
around begin ->  before -> AfterThrowing -> after

表达式Pointcut

主要语法

指示器(designators

  • 匹配方法

    • execution
  • 匹配参数

    • args
  • 匹配对象

    • this
    • bean
    • target(类)
  • 匹配包/类型

    • within (类)
  • 匹配注解

    • @args
    • @target(类)
    • @within(类)
    • @annotation

通配符(wildcards

  • * 匹配任意字符
  • .. 匹配指定类及其子类
  • + 匹配任意数的子包或参数

运算符(operators

  • &&
  • ||
  • !

表达式语法

execution

1
execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern)throws-pattern?)

其中 三个必须的:

  • returning type pattern
  • name pattern
  • parameters pattern

示例

  • execution(* com.*.*(..)) 匹配 com 包里类的任意方法
  • execution(* com..*.*(..)) 匹配 com 包及其所有子包里类的任意方法
  • execution(* com..Demo*.*(..)) 匹配 com 包及其所有子包里以Demo开头类的任意方法

within

  • within(@org.springframework.web.bind.annotation.RestController *) 匹配注解下任意类的任意方法
  • within(com.) 匹配 com 包里的任意类
  • within(com..) 匹配 com 包及其所有子包里的任意类

this

  • this(com.IService) 匹配IService接口的所有实现类

@within

  • @within(org.springframework.web.bind.annotation.RestController) 匹配注解下任意类的任意方法

@target

  • @target(org.springframework.web.bind.annotation.RestController) 匹配注解下任意类的任意方法

@annotation

  • @annotation(org.springframework.transaction.annotation.Transactional)匹配注解下的方法

常用示例

扫描注解标注的方法

1
2
3
4
5
6
public class AspectjAop{
@Pointcut("@annotation(io.swagger.v3.oas.annotations.Operation)")
public void operationPointCut() {

}
}

扫描注解标注的类

1
2
3
4
5
6
public class AspectjAop{
@Pointcut("within(@org.springframework.web.bind.annotation.RestController *))
public void operationPointCut() {

}
}

多个条件

1
2
3
4
5
6
public class AspectjAop{
@Pointcut("within(@org.springframework.web.bind.annotation.RestController || within(@org.springframework.stereotype.Controller *)")
public void operationPointCut() {

}
}

全部表达式

1
2
new InternalUseOnlyPointcutParser(ClassLocader)
[call, @target, target, execution, reference pointcut, adviceexecution, get, initialization, preinitialization, set, @within, withincode, @withincode, staticinitialization, @this, handler, this, within, @annotation, args, @args]

自定义 AOP 表达式

1
2
3
4
5
6
7
8
9
10
11
12
13
public class Demo(
public void test(){
String expression = "execution(* com..*Controller.*(..))";
AspectJExpressionPointcut pointcutParameterNames = new AspectJExpressionPointcut(Demo.class,
new String[0], new Class[0]);
pointcutParameterNames.setExpression(expression);
boolean matches = pointcutParameterNames.matches(ApiController.class);
log.debug("匹配 ApiController.class=>{}", matches);
assert matches;
matches = pointcutParameterNames.matches(ApiController.class.getMethod("RequestMapping", String.class), ApiController.class);
log.debug("匹配 ApiController.RequestMapping=>{}", matches);
}
)

本文地址: https://github.com/maxzhao-it/blog/post/44534123/