【SpringBoot】AOP 编程Demo

如果饿了就吃,困了就睡,渴了就喝,人生就太无趣了
源码地址:https://github.com/keer123456789/springbootstudy/tree/master/aopdemo


1.依赖引入

		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

2.创建切面

创建切面类AspectLog,该类作用是在方法前后打印日志。代码如下:

  • @Component 注解将切面类声明为bean,注入到spring容器中。
  • @Aspect注解将类声明为切面类
  • @Pointcut定义切点(用于准确定位应该在什么地方应用切面通知),execution用来定位切点,使用方法如图1:可以是使用通配符*匹配任意字符。 在这里插入图片描述
  • @Before 在方法前执行
  • @After 在方法后执行
  • @AfterReturning 在方法执行后返回一个结果后执行
  • @AfterThrowing 在方法执行过程中抛出异常的时候执行
  • @Around环绕通知,可以完成前置统通知和后置通知,使用该注解的方法的入参必须为ProceedingJoinPointProceedingJoinPoint.process()执行被切面的方法,可以完成前面四个注解的全部功能。可以看到配置了两个切点,第二个为@Around使用,第一个被其他通知使用。
@Component
@Aspect
public class AspectLog {
    protected Logger logger= LoggerFactory.getLogger(this.getClass());

    @Pointcut("execution(public * com.keer.aopdemo.Controller.get1(..))")
    public void aspectLog1() {
    }

    @Pointcut("execution(public * com.keer.aopdemo.Controller.get2(..))")
    public void aspectLog2() {
    }

    @Before("aspectLog1()")
    public void doBefore(JoinPoint joinPoint){
        List<String> args=new ArrayList<>();
        for(Object arg:joinPoint.getArgs()){
            args.add((String) arg);
        }
        logger.info("AOP: 方法前执行");
        logger.info("AOP: 方法名:"+joinPoint.getSignature().getName()+",方法参数:"+args.toString());
    }

    @After("aspectLog1()")
    public void doAfter(JoinPoint joinPoint){
        logger.info("AOP: 方法结束执行");
    }

    @AfterReturning("aspectLog1()")
    public void doAfterReturn(JoinPoint joinPoint){
        logger.info("AOP: 方法执行结束返回结果后执行");
    }
    @AfterThrowing("aspectLog1()")
    public void deAfterThrowing(JoinPoint joinPoint){
        logger.info("AOP: 方法抛出异常后执行");
    }

    @Around("aspectLog2()")
    public void doAround(ProceedingJoinPoint joinPoint){
        try {
            List<String> args=new ArrayList<>();
            for(Object arg:joinPoint.getArgs()){
                args.add((String) arg);
            }
            logger.info("AOP: 方法前执行");
            logger.info("AOP: 方法名:"+joinPoint.getSignature().getName()+",方法参数:"+args.toString());
            joinPoint.proceed();
            logger.info("AOP: 方法执行结束返回结果后执行");
        }catch (Throwable e){
            logger.info("AOP: 方法抛出异常后执行");
        }
    }

}

3.创建Controller进行测试

该类中创建了两个Web请求方法,第二个使用@Around注解的切点方法,第一个方法是使用其他注解的切点方法。

@RestController
public class Controller {
    protected Logger logger = LoggerFactory.getLogger(this.getClass());

    @GetMapping("/get1/{name}")
    public String get1(@PathVariable String name) {
        logger.info("接收到请求:/get1, 数据参数:" + name);
        return name + ",welcome to AOP";
    }

    @GetMapping("/get2/{name}")
    public String get2(@PathVariable String name) {
        logger.info("接收到请求:/get2, 数据参数:" + name);
        return name + ",welcome to AOP";
    }
}

访问:http://127.0.0.1:8080/get1/keer,结果如图2:

在这里插入图片描述

访问:http://127.0.0.1:8080/get2/keer,结果如图3:

在这里插入图片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章