springboot 使用Aop

简介

  1. AOP:面向切面(方面)编程,扩展功能不修改源代码实现
  2. AOP采取横向抽取机制,取代了传统纵向继承体系重复性代码
  3. AOP底层使用动态代理实现
    • 有接口情况使用动态代理创建接口实现类代理对象
    • 没有接口情况使用动态代理创建类的子类代理对象
 import lombok.extern.slf4j.Slf4j;
 import org.aspectj.lang.JoinPoint;
 import org.aspectj.lang.annotation.*;
 import org.springframework.core.annotation.Order;
 import org.springframework.stereotype.Component;
 import org.springframework.web.context.request.RequestContextHolder;
 import org.springframework.web.context.request.ServletRequestAttributes;

 import javax.servlet.http.HttpServletRequest;
 import java.util.Arrays;

 /**
 * 使用AOP记录访问日志
 * 使用@Before在切入点开始处切入内容
 * 使用@After在切入点结尾处切入内容
 * 使用@AfterReturning在切入点return内容之后切入内容(可以用来对处理返回值做一些加工处理)
 * 使用@Around在切入点前后切入内容,并自己控制何时执行切入点自身的内容
 * 使用@AfterThrowing用来处理当切入内容部分抛出异常之后的处理逻辑
 * 
 * 注解:
 * Aspect:AOP
 * Component:Bean
 * Slf4j:可以直接使用log输出日志
 * Order:多个AOP切同一个方法时的优先级,越小优先级越高越大。
 * 在切入点前的操作,按order的值由小到大执行
 * 在切入点后的操作,按order的值由大到小执行
 */

@Aspect
@Component
@Slf4j
@Order(1)
public class LogAspect {
    /**
     * 线程存放信息
     */
    ThreadLocal<Long> startTime = new ThreadLocal<>();

    /**
     * 定义切入点
     * 第一个*:标识所有返回类型
     * 字母路径:包路径
     * 两个点..:当前包以及子包
     * 第二个*:所有的类
     * 第三个*:所有的方法
     * 最后的两个点:所有类型的参数
     */
    @Pointcut("execution(public * net.codingme.boot.controller..*.*(..))")
    public void webLog() {
    }

    /**
     * 在切入点开始处切入内容
     *
     * @param joinPoint
     */
    @Before("webLog()")
    public void doBefore(JoinPoint joinPoint) {
        // 记录请求时间
        startTime.set(System.currentTimeMillis());
        // 获取请求域
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();

        // 记录请求内容
        log.info("Aspect-URL: " + request.getRequestURI().toLowerCase());
        log.info("Aspect-HTTP_METHOD: " + request.getMethod());
        log.info("Aspect-IP: " + request.getRemoteAddr());
        log.info("Aspect-REQUEST_METHOD: " + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
        log.info("Aspect-Args: " + Arrays.toString(joinPoint.getArgs()));
    }

    /**
     * 在切入点之后处理内容
     */
    @After("webLog()")
    public void doAfter() {
    }

    /**
     * 在切入点return内容之后切入内容(可以用来对处理返回值做一些加工处理)
     */
    @AfterReturning(returning = "ret", pointcut = "webLog()")
    public void doAfterReturning(Object ret) throws Throwable {
        log.info("Aspect-Response: " + ret);
        Long endTime = System.currentTimeMillis();
        log.info("Aspect-SpeedTime: " + (endTime - startTime.get()) + "ms");
    }

}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值