Springboot中AOP的使用

AOP是spring的两个主要模块功能之一,总结一下aop的基本用法

切面类组成

首先需要在类中用@Aspect,说明这个类时切面类,这个类主要由两个部分组成:@PointcutAdvice

@Pointcut

@Pointcut是一个注解,标注在类中的方法上,主要的作用是说明要处理那些类和那些方法。

@Pointcut 里的参数式一个表达式,包括指示器、通配符和运算符。

指示器按功能主要包括5类:

  • 匹配方法:execution()
  • 匹配注解:@target() @arges() @within() @annotation()
  • 匹配包或类型:within()
  • 匹配对象:this() bean() target()
  • 匹配参数:arges()

    注意!! 只有匹配注解的前边有@符号

通配符主要包含3种:

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

运算符也主要包括3种:

  • &&:与
  • ||:或
  • !:非

Advice

Advice说明了要执行的时机,主要是标注的类的方法上。

Advice主要有5种注解:

  • @Before:前置通知
  • @After: 后置通知,方法执行完之后
  • @AfterReturning: 返回通知,成功执行之后
  • @AfterThrowing:异常通知,抛出异常之后
  • @Around:环绕通知

用法

@Pointcut用法

在@Pointcut中execution()的应用最广,所以主要以execution()为例说明@Pointcut的用法
execution()的语法为:
execution(方法修饰符(可选) 返回类型 方法名 参数 异常模式(可选))

1
2
@Pointcut("execution(public * com.example.aopdemo.Controller.*.*(..))")
public void excudeService(){}

这个java代码中:
第一个* 号说明返回值为任意类型
第二个*号说明是任意类
第三个* 号说明的是任意方法
.. 说明参数为任意个
所以整个 @Pointcut说明处理的是com.example.aopdemo.Controller包下所有的类以及类中所有的方法,方法参数不限的方法。

Advice用法

Advice的用法大同小异,主要的差别是执行的时机,所以,主要以@Before为例说明用法

1
2
3
4
5
6
7
8
@Before("excudeService()")
public void before(JoinPoint joinPoint){

MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
Method method=methodSignature.getMethod();
logger.info("-----------"+method.getName());
logger.info("---------before---------");
}

这个before方法说明在excudeService()这个@Pointcut处理的范围之内,所有方法运行之前先运行before函数。

完整Aspect类例子的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

@Aspect
@Component
public class AopConfig {

Logger logger = LoggerFactory.getLogger(AopConfig.class);

@Pointcut("execution(public * com.example.aopdemo.Controller.*.*(..))")
public void excudeService(){}

@Pointcut("execution(* *..find*(String)) && within(com.example..*) ")
public void matchLongArg(){}


@Before("excudeService()")
public void before(JoinPoint joinPoint){

MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
Method method=methodSignature.getMethod();
logger.info("-----------"+method.getName());
logger.info("---------before---------");
}


@After("excudeService()")
public void after(JoinPoint joinPoint){


Object [] args = joinPoint.getArgs();
for (int i = 0; i < args.length; i++) {
logger.info(String.valueOf(args[i]));
}

logger.info("---------after---------");
}


}
-------------本文结束感谢您的阅读-------------