SpringBoot 简单整合AOP

开发环境为 IDEA,jdk1.8,Maven,SpringBoot2.1.3

AOP使用场景很多,此示例场景为对 web 请求进行日志记录

一、在pom文件中导入AOP依赖

<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-aop -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

二、定义切面类,实现所需功能.根据需求,切面类可定义多个,且可以自定义切面类的执行顺序.

/**
 * 简单的aop日志配置
 *
 * @author YoonaLt
 * @date 2019/10/29
 */
@Aspect  // 标记此类为切面类
@Component
@Slf4j
@Order(value = 2)  // 切面类执行顺序权重
public class LogAspect {

    /**
     * 定义切入点,可以定义多个。@After(),@Before()等只需填写方法名"pointCut()","pointCut1()","pointCut2()"即可.
     * <p>
     * execution()的一些含义例如:
     * execution(public * com.yoona.aop.*.*(..)),"com.yoona.aop"包下不限返回值的公共方法执行
     * execution(* my*(..)),任何一个以"my"开头的方法执行
     * execution(* com.yoona.aop.AopController.*(..)),AopController接口下任意方法执行
     * 在多个表达式之间使用 ||,or表示"或",使用 &&,and表示"与",!表示"非".例如:execution()||execution()
     * <p>
     * 还有一些其他表达式,如within(),this(),target(),args(),bean()等,与execution()使用略有差异,这里就不一一介绍了.
     * 需要注意的是,当表达式书写错误时,会抛出异常:warning no match for this type name:com.xx.xx [Xlint:invalidAbsoluteTypeName]
     */
    @Pointcut("execution(* com.yoona.aop.AopController.*(..))")
    public void pointCut() {
    }

    /**
     * 也可以直接定义切入点,@Before("execution(public * com.yoona.*.*(..))"),这样就不必定义切入点 @Pointcut 了.
     *
     * @param joinPoint 连接点,可以获取切入点方法的一些信息
     */
    @Before("pointCut()")
    public void atBefore(JoinPoint joinPoint) {
        log.debug(" @Before 在方法执行前执行");
        log.debug("切入点的方法名为 " + joinPoint.getSignature().getName());
    }

    /**
     * 方法结束后执行,无论是正常结束还是抛出异常都会执行.
     */
    @After("pointCut()")
    public void atAfter() {
        log.debug(" @After 方法执行......");
    }

    /**
     * 方法正常返回后执行
     *
     * @param o 方法返回的值
     */
    @AfterReturning(pointcut = "pointCut()", returning = "o")
    public void atAfterReturning(Object o) {
        log.debug(" @AfterReturning 方法执行......");
        log.debug("方法的返回值为" + o.toString());
    }

    /**
     * 方法抛出异常时执行
     *
     * @param t 方法抛出的异常
     */
    @AfterThrowing(pointcut = "pointCut()", throwing = "t")
    public void atAfterThrowing(Throwable t) {
        log.debug(" @AfterThrowing 方法抛出异常时执行......");
        log.debug("方法抛出的异常为" + t.toString());
    }
}

 

/**
 * @author YoonaLt
 * @date 2019/10/29
 * 再定义一个执行其他功能的切面类
 */
@Aspect
@Component
@Slf4j
@Order(value = 1)
public class OtherAspect {

    /**
     * 其他功能切面类
     */
    @Before("execution(* com.yoona.aop.AopController.*(..))")
    public void atBefore() {
        RequestAttributes ra = RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes sra = (ServletRequestAttributes) ra;
        HttpServletRequest httpServletRequest = sra.getRequest();
        String method = httpServletRequest.getMethod();
        log.debug("其他功能切面类执行了" + "\nMethod:" + method + "\nCache-Control:" + httpServletRequest.getHeader("Cache-Control"));

    }
}

三、测试接口

/**
 * aop测试接口
 *
 * @author YoonaLt
 * @date 2019/10/29
 */
@Slf4j
@RestController
@RequestMapping(value = "aop")
public class AopController {

    @GetMapping(value = "test")
    public Integer aopTest() {
        log.debug("测试方法执行了");
        // 使方法抛出异常
        int i = 10 / 0;
        return 10;
    }
}

四、Run:

访问接口

 

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