中都

风习袅袅,盈水展千华,飞檐亭角清铃响。犹记当初,你回眸莞尔,一笑倾城百日香。

博客园 首页 新随笔 联系 订阅 管理

1、作用
主要主要是把非核心但必要的功能嵌入到核心的功能中去,也就是非核心的功能就是切面;

2、AOP中的概念

  • 切入点(pointcut):在那些类、那些方法上切入;
  • 通知(advice):在方法前、方法后、方法前后做什么;
  • 切面(aspect):切面 = 切入点+通知,既在什么时机、什么地方、作什么;
  • 织入(weaving):把切面加入对象,并创建出代理对象的过程;
  • 环绕通知:AOP中最强大、灵活的通知,它集成了前置和后置通知,保留了连接点原有的方法;

例如,日志,每个方法被访问执行结果等都需要被记录,以便后面排查问题,那日志就是切面,下面是一个例子:

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

/*
 * @Author lzq-zd
 * @Date 2021/12/27 21:43
 * @Description 日志切面
 **/
@Aspect
@Component
public class AopLog {
    private Logger logger = LoggerFactory.getLogger(this.getClass());

    // 线程局部变量,用户解决多线程中相同变量的访问冲突问题
    private ThreadLocal<Long> curTime = new ThreadLocal<>();

    @Pointcut("execution(public * com.study..*.*(..))")
    public void aopWebLog() {

    }

    @Before("aopWebLog()")
    public void doBefore(JoinPoint joinPoint) throws Throwable {
        curTime.set(System.currentTimeMillis());
        // 接收到请求,记录请求内容
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if(attributes == null) {
            logger.error("error: 请求体数据为空!");
            return;
        }
        HttpServletRequest request = attributes.getRequest();
        // 记录下请求内容
        logger.info("URL: "+request.getRequestURL().toString());
        logger.info("http-method: "+request.getMethod());
        logger.info("client-ip: "+request.getRemoteAddr());
        logger.info("class-method: "+joinPoint.getSignature().getDeclaringTypeName()+"."+joinPoint.getSignature().getName());
        logger.info("params: "+getMethodParams(joinPoint));
    }

    @AfterReturning(pointcut = "aopWebLog()",returning = "retObject")
    public void doAfterReturning(Object retObject) throws Throwable {
        // 处理完成请求,记录返回内容
        logger.info("result: "+retObject);
        logger.info("time: "+(System.currentTimeMillis()-curTime.get()));
    }

    // 方法抛出异常退出时执行的通知
    @AfterThrowing(pointcut = "aopWebLog()",throwing = "ex")
    public void addAfterThrowingLogger(JoinPoint joinPoint,Exception ex) {
        logger.error("执行 "+" 异常",ex);
    }

    /**
     * 获取方法参数
     * @param joinPoint
     * @return
     */
    private List<Object> getMethodParams(JoinPoint joinPoint){
        List<Object> result = null;
        if(joinPoint == null){
            return new ArrayList<>();
        }
        Object[] o = joinPoint.getArgs();
        result = o == null ? Collections.emptyList() : Lists.newArrayList(o);
        Iterator<Object> it = result.iterator();
        while (it.hasNext()) {
            Object arg = it.next();
            if (arg instanceof BindingResult) {
                it.remove();
            }
            if (arg instanceof ServletRequest) {
                it.remove();
            }
        }
        return result;
    }
}
@RestController
public class TestAopLogController {
    @GetMapping("/aoptest/{name}")
    public String aopTest(@PathVariable("name")String name) {
        return name+"hello !";
    }
}

image

posted on 2021-12-27 23:19  中都  阅读(29)  评论(0)    收藏  举报
Live2D