AOP自定义注解保存到MongoDB数据库

news2024/7/6 17:45:11

如果你想用mongoDB做全局日志记录,比如记录controller方法执行相关数据,比如像这样。

整个流程:先写自定义注解。定义一个日志对象,字段属性设置好。 写aop 规范自定义注解如何使用,在其中通过切点和反射把相关参数存到日志对象,然后再用MongoTemplate的自带方法,保存到MongoDB数据库。

1.下载安装mongodb、设置全局变量、开机自启动.

1.1 参考这篇,写得非常详细了。

MongoDB的安装配置教程(很详细,你想要的都在这里)【我直接把图像软件Compass一并下载安装了,方便查看数据】

2.SpringBoot整合MongoDB,可参考这篇。

SpringBoot整合MongoDB

2.1 导入依赖

 <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>

2.2 yml文件配置

spring:
  data:
    mongodb:
      host: 127.0.0.1 #指定MongoDB服务地址
      port: 27017 #指定端口,默认就为27017
      database: systemLog #指定使用的数据库(集合)
      authentication-database: admin # 登录认证的逻辑库名
#     username: admin #用户名
#     password: abc123456 #密码

2.3 创建日志实体类(你想保存哪些信息)

@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Document(collection = "systemLogger")
public class SystemLogger {

    //用户名
    private String username;
    //TODO 请求方式
    private String requestMethod;
    //controller方法
    private String controllerLink;
    //模块名称(写在注解上的value)
    private String mode;
    //TODO 请求人ip地址
    private String ip;
    //操作时间
//    @JSONField(format = "yyyy-MM-dd mm:HH:ss")
    private String operationTime;
    //耗时
    private Long time;
}

2.4 创建自定义注解

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)

public @interface SystemLog {
    String value() default "";//当前模块描述
    String requestMethod()default "";//请求方法
}

2.5 创建 aop 写自定义注解执行逻辑 

aop:面向切面编程。将于业务无关,却对多个对象产生影响的的公共行为和逻辑。常用来保存系统日志。

package com.woniu.sys.aop; //根据你的包来
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.woniu.sys.mapper.UserMapper;
import com.woniu.sys.pojo.SystemLogger;
import com.woniu.sys.annotation.SystemLog;
import com.woniu.sys.pojo.User;//根据你的包来
import com.woniu.sys.utils.Application;//这个是我的工具类,解析请求里的token拿userId的
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
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.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Date;

@Aspect
@Component

public class SystemLogAOP {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private UserMapper userMapper;

    //切点表达式 拿执行方法的相关参数
    @Around("@annotation(com.woniu.sys.annotation.SystemLog)")
    public Object log(ProceedingJoinPoint joinPoint) throws Throwable {

        //拿方法上的注解
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        SystemLog annotation = method.getAnnotation(SystemLog.class);
        //注解上的value
        String mode = annotation.value();

        //当前操作时间
        long startTime = System.currentTimeMillis();
        Date date = new Date(startTime);
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String operationTime = simpleDateFormat.format(date);
        //执行方法
        Object proceed = joinPoint.proceed();
        //结束时间
        long endTime = System.currentTimeMillis();

        //耗时
        long time = endTime - startTime;
        
        //当前操作人用户名
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper();
        queryWrapper.eq(User::getId, Application.getUserId());
        User user = userMapper.selectOne(queryWrapper);
        
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();

        // 获取控制器路径
        String path = request.getRequestURI();

        // 获取控制器方法的请求方式
        String requestMethod = annotation.requestMethod();

        //请求人Ip
        String ip = request.getRemoteAddr();
        //组装日志对象
        SystemLogger systemLogger = SystemLogger.builder().ip(ip).username(user.getUsername()).time(time).operationTime(operationTime).mode(mode).controllerLink(path).requestMethod(requestMethod).build();

        //持久化保存
        mongoTemplate.save(systemLogger);
        return proceed;
    }





}

 

2.6 把注解贴在需要的方法上

我这里是贴在controller里的某个方法上。

 //找所有角色分类
    @SystemLog(value = "找所有角色分类",requestMethod = "Get")
    @GetMapping("/roleType")
    public ResData getRoleType(){
        LambdaQueryWrapper queryWrapper2 = new LambdaQueryWrapper();
        List<Role> allRoleList = roleMapper.selectList(queryWrapper2);
        return ResData.ok(allRoleList);
    }

2.7 apifox 测试

 2.8 MongoDB里查看document数据

 

如果不会用apifox,可以看这篇 Apifox快速扫盲。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/816324.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

机器学习笔记之优化算法(五)线搜索方法(步长角度;非精确搜索;Armijo Condition)

机器学习笔记之优化算法——线搜索方法[步长角度&#xff0c;非精确搜索&#xff0c;Armijo Condition] 引言回顾&#xff1a;关于 f ( x k 1 ) ϕ ( α ) f(x_{k1}) \phi(\alpha) f(xk1​)ϕ(α)的一些特性非精确搜索近似求解最优步长的条件 Armijo Condition \text{Armijo…

行业追踪,2023-07-31,板块多数都是指向消费

自动复盘 2023-07-31 凡所有相&#xff0c;皆是虚妄。若见诸相非相&#xff0c;即见如来。 k 线图是最好的老师&#xff0c;每天持续发布板块的rps排名&#xff0c;追踪板块&#xff0c;板块来开仓&#xff0c;板块去清仓&#xff0c;丢弃自以为是的想法&#xff0c;板块去留让…

【数据挖掘竞赛】——科大讯飞:锂离子电池生产参数调控及生产温度预测挑战赛

🤵‍♂️ 个人主页:@Lingxw_w的个人主页 ✍🏻作者简介:计算机科学与技术研究生在读 🐋 希望大家多多支持,我们一起进步!😄 如果文章对你有帮助的话, 欢迎评论 💬点赞👍🏻 收藏 📂加关注+ ​ 【科大讯飞】报名链接:https://challenge.xfyun.cn?invitaC…

JAVASE---类和对象

1. 面向对象的初步认知 1.1 什么是面向对象 Java是一门纯面向对象的语言(Object Oriented Program&#xff0c;简称OOP)&#xff0c;在面向对象的世界里&#xff0c;一切皆为对象。面向对象是解决问题的一种思想&#xff0c;主要依靠对象之间的交互完成一件事情。用面向对象的…

Mysql 查询统计最近12个月的数据

包括当月: SELECTt1.yf AS month,count( t2.uuid ) AS total FROM(SELECTDATE_FORMAT(( CURDATE()), %Y-%m ) AS yf UNIONSELECTDATE_FORMAT(( CURDATE() - INTERVAL 1 MONTH ), %Y-%m ) AS yf UNIONSELECTDATE_FORMAT(( CURDATE() - INTERVAL 2 MONTH ), %Y-%m ) AS yf UNION…

Microsoft Visual C++ 14.0 is required.

Microsoft Visual C 14.0 is required. Get it with “Microsoft Visual C Build Tools 当我们安装绝大部分python包的时候可以通过pip install 或者 conda install解决&#xff0c;但是任然有些包是安装不了的&#xff0c;比如我的就会报Microsoft Visual C 14.0 is required…

gcc编译方法、静态链接库、动态链接库用法

可执行程序的编译过程 第一步&#xff1a;预处理&#xff08;将宏展开&#xff09; gcc -E main.c -o main.i 第二步&#xff1a;编译成汇编指令 gcc -S main.i -o main.s 第三步&#xff1a;编译成目标文件&#xff0c;准备链接工作 gcc -c main.s -o main.o 第四步&am…

对话CSDN副总裁-邹欣:先行动的才是赢家,践行长期主义的价值创造者终将收获价值 | COC上海城市开发者社区

文章目录 ⭐️ COC上海城市开发者社区的首次集结契机⭐️ 关于 "技术人如何应对35岁中年危机"&#x1f31f; 30岁了没转管理&#xff0c;应该焦虑么&#xff1f;&#x1f31f; 30岁没转管理&#xff0c;是否还有其他选择&#xff1f; ⭐️ 践行长期主义的价值创造者终…

力扣SQL之路:窗口函数应用

文章目录 1.引言2.力扣SQL题目3. 解题策略4.代码实现5.总结 1.引言 窗口函数是 SQL 中一种强大的分析函数&#xff0c;它可以在结果集中创建一个窗口&#xff0c;并对窗口内的数据进行计算和分析。在力扣&#xff08;LeetCode&#xff09;的 SQL 题目中&#xff0c;窗口函数经…

这三件事没理顺,你过不了软考

下午好&#xff0c;我的网工朋友 上周软考成绩出来了&#xff0c;大家都过了没&#xff1f; 我看好多人都说早上的题目稳过&#xff0c;下午的好多都挂了。 软考每年这个通过率&#xff0c;确实是一言难尽。 到底怎么样才能过&#xff0c;自学、培训&#xff0c;各种诀窍&am…

最新多模态3D目标检测论文汇总(PDF+代码)

目前在自动驾驶领域&#xff0c;多模态3D目标检测是一个非常重要的研究热点。由于引入了其他传感器数据&#xff0c;多模态3D目标检测在性能上明显优于纯视觉的方案&#xff0c;可以同时预测周围物体的类别、位置和大小&#xff0c;因此对于自动驾驶领域的同学来说&#xff0c;…

【gitlib】linux系统rpm安装gitlib最新版本

目录 下载gitlib安装包 安装需要的依赖 设置开机启动 安装邮件服务器并设置开机启动 rpm执行安装gitlib 修改gitlib.rb文件的属性 修改完毕后执行更新配置 查看gitlib运行 查看gitlib初始化root密码 gitlib入口访问地址 下载gitlib安装包 Index of /gitlab-ce/yum/el7/…

龙蜥社区用户案例征集开始啦,欢迎投稿!

征集倡议 龙蜥社区在 2022 年首次发布了《2022 龙蜥操作系统生态用户实践精选》&#xff0c;为龙蜥广大用户提供了成熟实践样板。随着社区的迅速发展&#xff0c;龙蜥生态和用户的规模迅速壮大&#xff0c;为了更好的服务于广大龙蜥用户&#xff0c;现面向各行业征集龙蜥用户案…

Mybatis源码解析(三)------SqlSession

Mybatis源码解析&#xff08;三&#xff09;------SqlSession 序言SqlSession接口SqlSession的实现类DefaultSqlSessionSelect获取Statement查询 序言 Mybatis里面的核心就是SqlSession这个接口&#xff0c;前面我们已经研究了Mybatis的配置过程和Mapper的注册过程&#xff0c…

jsp实现打印功能

1.先实现列表页查询 2.做一个打印按钮 function plprint(){var rows $(#whYcfTzList).datagrid(getData);var ORGCODE$(input[nameORGCODE]).val();var ISCONTAIN$(input[nameISCONTAIN]).val();var RECCODE$(input[nameRECCODE]).val();var CUSTOMERNAME$(input[nameCUSTOM…

安卓抓包神器黄鸟HttpCanary安装配置及使用教程

1、下载安装包 黄鸟抓包下载地址 2、安装下载的apk 3、证书安装问题 vivo手机我安装时打开黄鸟app&#xff0c;会直接弹出&#xff0c;直接安装即可 其他手机&#xff0c;需要去系统设置中安装 3.1 搜索 证书&#xff0c;选择CA证书 3.2 进行本人操作验证 3.3 安装HttpCa…

【LeetCode】下降路径最小和

下降路径最小和 题目描述算法分析编程代码 链接: 下降路径最小和 题目描述 算法分析 编程代码 class Solution { public:int minFallingPathSum(vector<vector<int>>& matrix) {int n matrix.size();vector<vector<int>> dp(n1,vector(n2,INT_M…

【密码学】五、序列密码

序列密码 1、概述1.1序列密码的分类1.1.1同步序列密码1.1.2自同步序列密码 2、序列密码的组成2.1密钥序列生成器KG2.2有限状态自动机 3、LFSR 1、概述 采用一个短的种子密钥来控制某种算法获得长的密钥序列的办法&#xff0c;用以提供加解密&#xff0c;这个种子密钥的长度较短…

java实现文件下载

1.文件上传 文件上传&#xff0c;也称为upload&#xff0c;是指将本地图片、视频、音频等文件上传到服务器上&#xff0c;可以供其他用户浏览或下载的过程。文件上传在项目中应用非常广泛&#xff0c;我们经常发微博、发微信朋友圈都用到了文件上传功能。 import com.itheima.…

Leetcode-每日一题【剑指 Offer II 006. 排序数组中两个数字之和】

题目 给定一个已按照 升序排列 的整数数组 numbers &#xff0c;请你从数组中找出两个数满足相加之和等于目标数 target 。 函数应该以长度为 2 的整数数组的形式返回这两个数的下标值。numbers 的下标 从 0 开始计数 &#xff0c;所以答案数组应当满足 0 < answer[0] &l…