Spring AOP切面的应用

Spring Aop切面参数JoinPoint详解

链接:Spring Aop切面参数JoinPoint详解

Spring AOP简单实现全局日志监控请求

前言

Spring AOP意为:面向切面编程。同时AOP也是基于动态代理和反射进行实现,利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。在学习AOP之前有兴趣的同学可以先了解一下IOC,链接:Spring IOC详解

AOP日志功能实战

在此demo只介绍了以自定义注解标记的方法作为切点。首先我们先自定义一个注解,里面包含了日志的信息。

RequestTime.java

import java.lang.annotation.*;

/** 请求时间注解 @Author liaopj 2022/4/12 */
@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestTime {
    /**
     * 日志模块
     */
    public String title() default "";
}

接下来编写我们的切面类,这里需要注意我们可以先看一下切面表达式,我们也可以自定义切面表达式来实现我们想要实现切面的地方,链接:切面表达式

RequestTimeAspect.java

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

/** 请求日志aop @Author liaopj 2022/4/12 */
@Aspect
@Component
@Slf4j
public class RequestTimeAspect {

  /**
   * 环绕请求 只对刚刚我们自定义注解标记的方法生效,当然也可以指定某一个包或者某多个包下的所有方法生效
   * @Around注解可以用来在调用一个具体方法前和调用后来完成一些具体的任务
   * 更多注解可以看上方的Spring Aop切面参数JoinPoint详解链接
   * @param joinPoint 切点
   */
  @Around(value = "@annotation(requestTime)")
  public Object RequestTime(ProceedingJoinPoint joinPoint, RequestTime requestTime)
      throws Throwable {
    // 请求前的时间戳
    long startTime = System.currentTimeMillis();
    Object proceed = joinPoint.proceed();
    // 请求后的时间戳
    long endTime = System.currentTimeMillis();
    // 请求详细信息
    HttpServletRequest request =
        ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
    String method = request.getMethod();
    String requestURI = request.getRequestURI();
    long Time = endTime - startTime;
    log.info(
        "请求信息method:{},requestURI:{},time:{}ms,日志模块:{}",
        method,
        requestURI,
        Time,
        requestTime.title());
    return proceed;
  }

这时候我们的切面就定义好了,下面就来使用我们的AOP

比如这时候我有一个往redis里添加缓存的接口,我需要监控这个接口的请求时间或者请求路径等一些信息。代码如下:

RedisDemoController.java

import com.liao.aspectj.RequestTime;
import com.liao.redis.util.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;

/** @Author liaopj 2022/4/11 */
@RestController
@RequestMapping("/redis")
@Slf4j
public class RedisDemoController {

  @Autowired private RedisUtil redisUtil;

  @GetMapping("/Test")
  @RequestTime(title ="redis模块")
  public void redisTest() {
    Map<String, String> map = new HashMap<String, String>();
    map.put("test", "test");
    redisUtil.setCacheMap("REDIS_DEMO:redisTest", map);
    redisUtil.expire("REDIS_DEMO:redisTest", 10);
    log.info("redis中成功缓存,过期时间为time:{}s,key:{},value:{}", "10", "REDIS_DEMO:redisTest", map);
  }
  
  @GetMapping("/Test02")
  public void redisTest02() {
   System.out.println("当我们调用此接口时,他没有被@RequestTime标记,所以我们AOP不会生效");
  }
}

这时候我们自定义的AOP就生效了

在这里插入图片描述

这里一个是我们接口打印的日志,一个是AOP打印的请求信息日志。

此时,一个Spring AOP的一个小demo就完成了。具体AOP的应用还有很多知识。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值