基于Boot+JPA的日志管理

目的:对特定字段的值变更进行监测

实现思路:

  • 猜测1:通过数据库里面写触发器和监听器来实现
  • 猜测2:通过消息队列来实现
  • 猜测3:通过AOP来实现

实际实现思路:

  • 主要是通过监听器来实现对字段的监听,原想通过AOP来做这件事,后来因为牵涉较大,故改用简单易实现的方式来做。

核心组件

  • 自定义监听器实现hibernate提供的PostInsertEventListener,PostUpdateEventListener,PostDeleteEventListener接口类,分别监听不同的数据库操作类型,

如:新增、更新、删除。

推荐博客http://www.iyujian.me/java/log-manager-by-PostInsertEventListener-PostUpdateEventListener-PostDeleteEventListener.html?nsukey=jYV1ZgysAvXxmBWEdQEMYxqB2Hcs4l1yYqmksaUhz8%2BC8ZwUqxv%2B6OJnGFsEmzDmCKaybClqIEAlwxkZ8hh86ZchLBXA4hJecwyEw80NSzkBciQzwuBp19pMphgWgOHWanuPxTcNCE6nxQW0zykhr0RvrsvyRV0jPiLwqg223vY4UwIAQkIHWno2tLfc4NgT35%2Bno0wfeiLpMLsLTlaYDQ%3D%3D

背景描述

  • 监听特定字段的增删改操作,并记录到日志管理表中间。因为项目还涉及到分布式的概念,所以要将该保存日志的功能抽到一个公共模块里面。在要进行日志监听的服务中实现监听器,如果监听到那么就发送请求,进行服务互调,调用公共模块的保存日志记录的方法。
  • 踩坑:我在onPostInsert方法中做了对日志表的插入,导致了堆栈溢出。因为本身该方法就是一个监听新增操作事件,在新增里面新增操作,就会造成死循环。
  • 约定俗成的规矩:要监听的表字段和表名要遵循驼峰法原则。

举例:以新增操作举例。

  • 第一步:调用公共模块的查询日志管理表和日志管理字段表,得到要监听的表名和字段的集合,封装成Map<String param1,List<String> param2>格式,param1代表表名,param2代表字段集。
  • 第二步:从方法的参数PostUpdateEvent event中获取对应的表名、字段名、字段值。

    ①获取表名:event.getEntity().getClass().getSimpleName();

    ②获取字段名:event.getPersister().getPropertyNames();

    ③获取字段值:event.getState();

  • 第三步:根据本次操作的字段名称去匹配监听字段集合,如果在则调用基础服务的日志保存操作,如果不在则跳过。
  • 备注:此处还引入了redis缓存,调用基础服务获取监听字段集,塞入缓存,在有效时间内不在进行跨服务调用,直接从缓存中获取所需的字段集。因为存储的是String类型的json,所以这里免不了还要使用到一些字符串截取的操作。

待完善点:在服务调用的时候,打印有效日志。需要考虑跨服务调用的时候,如果失败了,进行事务回滚。

优化点:

1、因为监听器实现的业务逻辑对每个服务来说是不变的,所以不该每个服务写一遍,应该将其打包成jar,以开关的形式直接嵌入到需要日志服务记录的服务中。

2、基于Eclipse的打包参照博客:https://blog.csdn.net/weixin_44333583/article/details/90439633

3、打完嵌入之后发现监听器的日志没有被输出,证明没有被Spring扫描到。那么需要搜索Spring如何去扫描jar包中的注解类。

参照博客:https://www.cnblogs.com/skyme/archive/2011/08/11/2134918.html

至此大功告成,哪里需要哪里引。学习之路很漫长,有时候一步不能完成,就分多步来实现。

2019-12-02

 

 

 

posted @ 2019-12-02 15:45  虫虫低语  阅读(606)  评论(0编辑  收藏  举报