SpringBoot注解切面编程

pom文件里加入依赖

        <!-- 切面编程 @Aspect、@Pointcut等依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>

新建一个annotation目录放置自定义的注解类,在这个目录里新建一个注解类MyAnnotation,在控制器方法上加这个注解就会加入过滤

package com.zeromemos.annotation;

import java.lang.annotation.*;

@Documented
@Target(ElementType.METHOD) // 注解只能放方法上
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
    String description() default "自定义的注解";
}

新建一个aspect目录放置切面类,在这个目录下新建一个切面类MyAspect

package com.zeromemos.aspect;

import com.zeromemos.annotation.MyAnnotation;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

@Component
@Aspect
public class MyAspect {

    // 定义切点
    // 让所有有@MyAnnotation注解的方法都执行切面方法
    @Pointcut("@annotation(myAnnotation)")
    public void aPointcut(MyAnnotation myAnnotation){ }

    /**
     * 环绕通知
     */
    @Around("aPointcut(myAnnotation)")
    public Object doAround(ProceedingJoinPoint joinPoint, MyAnnotation myAnnotation){
        Object result = null;

        try {
            System.out.println(myAnnotation.description() + " 调用方法 " + joinPoint.getSignature().getName() + " 环绕前置通知");
            // 执行被拦截方法 result 的值就是被拦截方法的返回值
            result = joinPoint.proceed();
            System.out.println(myAnnotation.description() + " 调用方法 " + joinPoint.getSignature().getName() + " 环绕返回通知");
        } catch (Throwable throwable) {
            throwable.printStackTrace();
            System.out.println(myAnnotation.description() + " 调用方法 " + joinPoint.getSignature().getName() + " 环绕异常通知");
        }
        return result;
    }

    @Before(("aPointcut(myAnnotation)"))
    public void before(MyAnnotation myAnnotation){
        System.out.println(myAnnotation.description() + "before");
    }

    @After(("aPointcut(myAnnotation)"))
    public void After(MyAnnotation myAnnotation){
        System.out.println(myAnnotation.description() + "After");
    }

    @AfterReturning(("aPointcut(myAnnotation)"))
    public void AfterReturning(MyAnnotation myAnnotation){
        System.out.println(myAnnotation.description() + "AfterReturning");
    }
}

在下面这个controller方法里加了注解测试

    @MyAnnotation
    @GetMapping("/easyCaptcha")
    public void easyCaptcha() throws IOException{
        System.out.println("开始验证码获取");
        CaptchaUtil.out(request, response);
        System.out.println("完成验证码获取");
    }

访问http://localhost:9001/captcha/easyCaptcha测试,切面方法执行顺序如下