依赖

  1. <!-- aop 依赖 -->
  2. <dependency>
  3. <groupId>org.springframework.boot</groupId>
  4. <artifactId>spring-boot-starter-aop</artifactId>
  5. </dependency>

aspectj 注解

  • @Aspect:声明该类为一个注解类;
  • @Pointcut:定义一个切点,后面跟随一个表达式,表达式可以定义为某个 package 下的方法,也可以是自定义注解等;
  • 切点定义好后,就是围绕这个切点做文章了:
    • @Before: 在切点之前,织入相关代码;
    • @After: 在切点之后,织入相关代码;
    • @AfterReturning: 在切点返回内容后,织入相关代码,一般用于对返回值做些加工处理的场景;
    • @AfterThrowing: 用来处理当织入的代码抛出异常后的逻辑处理;
    • @Around: 在切入点前后织入代码,并且可以自由的控制何时执行切点;
注解 说明
@Aspect 将一个 java 类定义为切面类
@Pointcut 定义一个切入点,可以是一个规则表达式,比如下例中某个 package 下的所有函数,也可以是一个注解等
@Before 在切入点开始处切入内容
@After 在切入点结尾处切入内容
@AfterReturning 在切入点 return 内容之后处理逻辑
@Around 在切入点前后切入内容,并自己控制何时执行切入点自身的内容
@AfterThrowing 用来处理当切入内容部分抛出异常之后的处理逻辑
@Order(100) OP 切面执行顺序, @Before 数值越小越先执行,@After 和 @AfterReturning 数值越大越先执行|@Order(100) AOP 切面执行顺序, @Before 数值越小越先执行,@After 和 @AfterReturning 数值越大越先执行

表达式

表达式

  1. execution(方法修饰符 返回类型 方法所属的包.类名.方法名称(方法参数)

/*
定义切点Pointcut
第一个号:表示返回类型, 号表示所有的类型
第二个号:表示类名,号表示所有的类
第三个号:表示方法名,号表示所有的方法
后面括弧里面表示方法的参数,两个句点表示任何参数
*/

eg

  1. //com.macro.mall.tiny.controller包中所有类的public方法都应用切面里的通知
  2. execution(public * com.macro.mall.tiny.controller.*.*(..))
  3. //com.macro.mall.tiny.service包及其子包下所有类中的所有方法都应用切面里的通知
  4. execution(* com.macro.mall.tiny.service..*.*(..))
  5. //com.macro.mall.tiny.service.PmsBrandService类中的所有方法都应用切面里的通知
  6. execution(* com.macro.mall.tiny.service.PmsBrandService.*(..))

关键字

切入点表达式关键词:

  1)execution:用于匹配子表达式。
//匹配com.cjm.model包及其子包中所有类中的所有方法,返回类型任意,方法参数任意

  1. @Pointcut("execution(* com.cjm.model..*.*(..))")
  2. public void before(){}

2)within:用于匹配连接点所在的Java类或者包。
//匹配Person类中的所有方法

  1. @Pointcut("within(com.cjm.model.Person)")
  2. public void before(){}

//匹配com.cjm包及其子包中所有类中的所有方法

  1. @Pointcut("within(com.cjm..*)")
  2. public void before(){ }


3) this:用于向通知方法中传入代理对象的引用。

  1. @Before("before() && this(proxy)")
  2. public void beforeAdvide(JoinPoint point, Object proxy){
  3. //处理逻辑
  4. }
  1. <br /> <br /> 4)target:用于向通知方法中传入目标对象的引用。
  1. @Before("before() && target(target)
  2. public void beforeAdvide(JoinPoint point, Object proxy){//处理逻辑}

5)args:用于将参数传入到通知方法中。

  1. @Before("before() && args(age,username)")
  2. public void beforeAdvide(JoinPoint point, int age, String username){
  3. }
  1. 6@within :用于匹配在类一级使用了参数确定的注解的类,其所有方法都将被匹配。
  1. @Pointcut("@within(com.cjm.annotation.AdviceAnnotation)") 所有被@AdviceAnnotation标注的类都将匹配
  2. public void before(){}
  1. 7@target :和@within的功能类似,但必须要指定注解接口的保留策略为RUNTIME
  1. @Pointcut("@target(com.cjm.annotation.AdviceAnnotation)")
  2. public void before(){}
  1. <br /> <br /> 8)@args :传入连接点的对象对应的Java类必须被@args指定的Annotation注解标注。
  1. @Pointcut("bean(person)")
  2. public void before(){}
  1. 9@annotation :匹配连接点被它参数指定的Annotation注解的方法。也就是说,所有被指定注解标注的方法都将匹配。
  1. @Pointcut("@annotation(com.cjm.annotation.AdviceAnnotation)")
  2. public void before(){}
  1. 10bean:通过受管Bean的名字来限定连接点所在的Bean。该关键词是Spring2.5新增的。
  1. @Pointcut("bean(person)")
  2. public void before(){}