SpringBoot AOP 实现埋点日志记录(完整源码)

本文介绍了如何使用Spring Boot AOP实现埋点日志记录,详细讲解了AOP的常用术语,并提供了完整的源码实现。通过自定义注解和切点,实现对方法运行时间、参数等信息的监控,帮助理解用户操作习惯并便于系统跟踪。
摘要由CSDN通过智能技术生成

写在开头:
我是「猿码天地」,一个热爱技术、热爱编程的IT猿。技术是开源的,知识是共享的!
写博客是对自己学习的总结和记录,如果您对Java、分布式、微服务、中间件、Spring Boot、Spring Cloud等技术感兴趣,可以关注我的动态,我们一起学习,一起成长!
用知识改变命运,让家人过上更好的生活,互联网人一家亲!
关注微信公众号【猿码天地】,获取更多干货技能,一起吃肉喝汤,陪你一起撸代码!

随着互联网技术的深入发展,各个系统的日活用户、访问量、点击量成指数上升,为保证系统的安全性、易用性,每个系统都需要对用户的访问做埋点记录、跟踪,从而获取用户常用的操作习惯,同时也方便系统管理人员对系统做日常记录、跟踪。

一、Spring Boot AOP

AOP:面向切面编程,相对于OOP面向对象编程,Spring的AOP的存在目的是为了解耦。AOP可以让一组类共享相同的行为。在OOP中只能继承和实现接口,且类继承只能单继承,阻碍更多行为添加到一组类上,AOP弥补了OOP的不足。还有就是为了清晰的逻辑,让业务逻辑关注业务本身,不用去关心其它的事情,比如事务。
实现方式:Spring的AOP是通过JDK的动态代理和CGLIB实现的。

二、AOP的常用术语

AOP有一堆术语,主要包括以下:
通知(Advice) 需要完成的工作叫做通知,就是你写的业务逻辑中需要比如事务、日志等先定义好,然后需要的地方再去用。
连接点(Join point) spring中允许使用通知的地方,基本上每个方法前后抛异常时都可以是连接点。
切点(Poincut) 筛选出的连接点,一个类中的所有方法都是连接点,但又不全需要,会筛选出某些作为连接点做为切点。
切面(Aspect) 通知和切点的结合,通知和切点共同定义了切面的全部内容,它是干什么的,什么时候在哪执行。
引入(Introduction) 在不改变一个现有类代码的情况下,为该类添加属性和方法,可以在无需修改现有类的前提下,让它们具有新的行为和状态。其实就是把切面用到目标类中去。
目标(target) 被通知的对象。也就是需要加入额外代码的对象,真正的业务逻辑被组织织入切面。
织入(Weaving) 把切面加入程序代码的过程。切面在指定的连接点被织入到目标对象中,在目标对象的生命周期里有多个点可以进行织入。

三、源码实现埋点日志记录

3.1 项目结构图

在这里插入图片描述

3.2 代码实现

  • 配置文件
    这里只有三个配置:
    server.port=8081,设置项目启动的端口号,防止被其他服务占用
    server.servlet.context-path: /aop,项目上下文
    spring.aop.auto=true,开启spring的aop配置,简单明了,不需要多配置其他的配置或注解。
server:
  port: 8081
  servlet.context-path: /aop

spring:
  aop:
    auto: true
  • AOP切面类
    这个是最主要的类,可以使用自定义注解或针对包名实现AOP增强。
    1)这里实现了对自定义注解的环绕增强切点,对使用了自定义注解的方法进行AOP切面处理。
    2)对方法运行时间进行监控。
    3)对方法名,参数名,参数值,对日志描述的优化处理。

    在方法上增加@Aspect注解声明切面 使用@Pointcut 注解定义切点,标记方法

    使用切点增强的时机注解:
    @Before 前置通知, 在方法执行之前执行
    @Around 环绕通知, 围绕着方法执行
    @AfterReturning 返回通知, 在方法返回结果之后执行
    @AfterThrowing 异常通知, 在方法抛出异常之后
    @After 后置通知, 在方法执行之后执行

package com.bowen.aspect;

import com.alibaba.fastjson.JSON;
import com.bowen.annotation.OperationLogDetail;
import com.bowen.model.OperationLog;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * <h3>AspectDemo</h3>
 * <p>AOP切面类</p>
 * @author : zhang.bw
 * @date : 2020-04-16 14:52
 **/
@Aspect
@Component
public class LogAspect {
   

   private static final Logger LOG = LoggerFactory.getLogger(LogAspect.class);

   /**
    * 定义切点
    * 此处的切点是注解的方式,也可以用包名的方式达到相同的效果
    * '@Pointcut("execution(* com.bowen.service.impl.*.*(..))")'
    */
   //@Pointcut("@annotation(com.bowen.annotation.OperationLogDetail)")
   @Pointcut("execution(* com.bowen.controller.*.*(..))")
   public void operationLog(){
   }


   /**
    * 环绕增强,相当于MethodInterceptor
    */
   @Around("operationLog()")
   public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
   
      Object res = null;
      long time = System.currentTimeMillis();
      try {
   
         res =  joinPoint.proceed();
         time = System.currentTimeMillis() - time;
         return res;
      } finally {
   
         try {
   
            //方法执行完成后增加日志
            addOperationLog(joinPoint,res,time);
         }catch (Exception e){
   
            LOG.error("LogAspect 操作失败:" + e.getMessage());
         }
      }
   }

   /**
    * 方法执行完成后增加日志
    * @param joinPoint
    * @param res
    * @param time
    */
   private void addOperationLog(JoinPoint joinPoint, Object res, long time){
   
      MethodSignature signature = (MethodSignature)joinPoint.getSignature();
      OperationLog operationLog =<
  • 7
    点赞
  • 50
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猿码天地

相互学习,谢谢您的打赏。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值