如果您需要对所有数据库操作进行自动审核 ,并且正在使用Hibernate…,则应使用Envers或spring data jpa auditing 。 但是,如果由于某些原因您不能使用Envers,则可以使用休眠事件侦听器和spring事务同步来实现类似的功能。

首先,从事件监听器开始。 您应该捕获所有插入,更新和删除操作。 但是有一点棘手的问题–如果出于某种原因需要刷新会话,则无法直接使用传递给事件侦听器的会话执行该逻辑。 以我为例,我必须获取一些数据,然后休眠开始向我抛出异常(“ id为null”)。 多个来源确认您不应在事件侦听器中与数据库进行交互。 因此,您应该存储事件以供以后处理。 您可以将侦听器注册为spring bean ,如下所示 。

@Component
public class AuditLogEventListenerimplements PostUpdateEventListener, PostInsertEventListener, PostDeleteEventListener {@Overridepublic void onPostDelete(PostDeleteEvent event) {AuditedEntity audited = event.getEntity().getClass().getAnnotation(AuditedEntity.class);if (audited != null) {AuditLogServiceData.getHibernateEvents().add(event);}}@Overridepublic void onPostInsert(PostInsertEvent event) {AuditedEntity audited = event.getEntity().getClass().getAnnotation(AuditedEntity.class);if (audited != null) {AuditLogServiceData.getHibernateEvents().add(event);}}@Overridepublic void onPostUpdate(PostUpdateEvent event) {AuditedEntity audited = event.getEntity().getClass().getAnnotation(AuditedEntity.class);if (audited != null) {AuditLogServiceData.getHibernateEvents().add(event);}}@Overridepublic boolean requiresPostCommitHanding(EntityPersister persister) {return true; // Envers sets this to true only if the entity is versioned. So figure out for yourself if that's needed}
}

注意AuditedEntity –这是一个自定义标记注释(retention = runtime,target = type),您可以将其放置在实体之上。

老实说,我没有完全了解Envers如何进行持久化 ,但是由于我也可以使用spring,因此在AuditLogServiceData类中,我决定使用spring:

/*** {@link AuditLogServiceStores} stores here audit log information It records all * changes to the entities in spring transaction synchronizaton resources, which * are in turn stored as {@link ThreadLocal} variables for each thread. Each thread * /transaction is using own copy of this data.*/
public class AuditLogServiceData {private static final String HIBERNATE_EVENTS = "hibernateEvents";@SuppressWarnings("unchecked")public static List<Object> getHibernateEvents() {if (!TransactionSynchronizationManager.hasResource(HIBERNATE_EVENTS)) {TransactionSynchronizationManager.bindResource(HIBERNATE_EVENTS, new ArrayList<>());}return (List<Object>) TransactionSynchronizationManager.getResource(HIBERNATE_EVENTS);}public static Long getActorId() {return (Long) TransactionSynchronizationManager.getResource(AUDIT_LOG_ACTOR);}public static void setActor(Long value) {if (value != null) {TransactionSynchronizationManager.bindResource(AUDIT_LOG_ACTOR, value);}}
}

除了存储事件之外,我们还需要存储执行操作的用户。 为了做到这一点,我们需要提供一个方法-参数级注释来指定一个参数。 在我的案例中,注释称为AuditLogActor (保留=运行时,类型=参数)。

现在剩下的将是处理事件的代码。 我们想在提交当前事务之前执行此操作。 如果提交后事务失败,则审计条目插入也将失败。 我们通过一点AOP来做到这一点:

@Aspect
@Component
class AuditLogStoringAspect extends TransactionSynchronizationAdapter {@Autowiredprivate ApplicationContext ctx; @Before("execution(* *.*(..)) && @annotation(transactional)")public void registerTransactionSyncrhonization(JoinPoint jp, Transactional transactional) {Logger.log(this).debug("Registering audit log tx callback");TransactionSynchronizationManager.registerSynchronization(this);MethodSignature signature = (MethodSignature) jp.getSignature();int paramIdx = 0;for (Parameter param : signature.getMethod().getParameters()) {if (param.isAnnotationPresent(AuditLogActor.class)) {AuditLogServiceData.setActor((Long) jp.getArgs()[paramIdx]);}paramIdx ++;}}@Overridepublic void beforeCommit(boolean readOnly) {Logger.log(this).debug("tx callback invoked. Readonly= " + readOnly);if (readOnly) {return;}for (Object event : AuditLogServiceData.getHibernateEvents()) {// handle events, possibly using instanceof}}

在我的情况下,我必须注入其他服务,并且spring抱怨相互依赖的bean,所以我改用了applicationContext.getBean(FooBean.class) 。 注意:确保您的方面被Spring所捕获–通过自动扫描,或通过xml / java-config显式注册它。

因此,已审核的呼叫将如下所示:

@Transactional
public void saveFoo(FooRequest request, @AuditLogActor Long actorId) { .. }

总结一下:休眠事件监听器将所有插入,更新和删除事件存储为spring事务同步资源。 一个方面用spring注册一个事务“回调”,在提交每个事务之前立即调用它。 在那里处理所有事件,并插入相应的审核日志条目。

这是非常基本的审核日志,可能在收集处理方面有问题,并且当然不能涵盖所有用例。 但这比手动审核日志处理要好得多,并且在许多系统中,审核日志是强制性功能。

翻译自: https://www.javacodegeeks.com/2016/07/custom-audit-log-spring-hibernate.html

Spring和Hibernate的自定义审核日志相关推荐

  1. spring 自定义日志_Spring和Hibernate的自定义审核日志

    spring 自定义日志 如果您需要对所有数据库操作进行自动审核 ,并且正在使用Hibernate-,则应使用Envers或spring data jpa auditing . 但是,如果由于某些原因 ...

  2. Spring Security使用Hibernate实现自定义UserDetails

    大多数时候,我们将需要在Web应用程序中配置自己的安全访问角色. 这在Spring Security中很容易实现. 在本文中,我们将看到最简单的方法. 首先,我们将在数据库中需要以下表格: CREAT ...

  3. 深入字节码操作:使用ASM和Javassist创建审核日志

    深入字节码操作:使用ASM和Javassist创建审核日志 原文链接:https://blog.newrelic.com/2014/09/29/diving-bytecode-manipulation ...

  4. Spring Boot 2.x的默认日志管理与Logback配置详解

    前沿技术早知道,弯道超车有希望 积累超车资本,从关注DD开始 Spring Boot在所有内部日志中使用Commons Logging,但是对底层日志的实现是开放的.在Spring Boot生态中,为 ...

  5. 【经典】Spring aop切面实现异步添加日志—完整版

    系统开发中我们常遇到要处理系统日志等信息的,在此我分享一篇 利用spring aop切面来异步添加日志的操作,其中用到了 队列和多线程,前面的博客有写. 第一步:创建log实体,根据自己业务而定, p ...

  6. 办公OA系统的设计与实现 软件工程 Struts、Spring和Hibernate(SSH)

    绪论 摘要 当今社会发展迅速,互联网相关技术快速在各行各业普及,智能办公的需求日益增长.同时,随着企业发展不断推进,规模越做越大,传统的纸笔和文件系统记录人员信息已经无法满足大数据时代成千上万员工职业 ...

  7. spring boot项目中使用logback日志详解

    1. spring boot中的默认日志 SpringBoot为Java Util Logging,Log4J2和Logback提供了默认配置.SpringBoot默认配置日志输出到控制台,同时还提供 ...

  8. java如何读取自定义log4j2_spring boot自定义log4j2日志文件的实例讲解

    背景:因为从 spring boot 1.4开始的版本就要用log4j2了,支持的格式有json和xml两种格式,此次实践主要使用的是xml的格式定义日志说明. spring boot 1.5.8.R ...

  9. 整合Struts2、Spring、Hibernate构建J2EE应用

    [论文摘要] J2EE即是以Java 2平台为基础的体系结构,又是一组旨在简化企业解决方案的开发.部署.运行.维护等相关复杂问题的技术规范与指南.Struts2.Spring.Hibernate是当今 ...

最新文章

  1. 腾讯云区块链,打造基础设施之上的生态系统
  2. ASP.NET BookMark
  3. vrish 删除虚机_使用Kvm命令集管理虚拟机
  4. 5天不再惧怕多线程——第三天 互斥体
  5. httpclient base64 文件上传_文件上传下载
  6. matlab贝叶斯优化工具箱_经济学人的神器——BEAR(贝叶斯估计、分析和回归工具包)...
  7. 递归-汉诺塔(代码、分析、汇编)
  8. Node.js学习之(第二章:exports和module.exports)
  9. 聊聊内卷之下,直博和读完硕士再读博该怎么选择?
  10. 23.多线程 实现的两种方式
  11. java heap排序_关于Java排序算法-堆排序(Heap Sort)
  12. paip. 解决java程序不能自动退出
  13. matlab每隔几个数求平均,每隔48个数求平均值
  14. 巅峰阁批量卡android,卡iPhoneQQ在线
  15. 不用担心JDK17收费了,Oracle 推出 JDK 8 的升级替代品
  16. 博图——生成和导入外部源文件
  17. 公共关系与人际交往能力
  18. testcenter自动化
  19. 微信小程序中的空格怎么打
  20. 10.1寸安卓通用车载导航

热门文章

  1. vue组件自定义v-model
  2. 总结Java常见面试题和答案
  3. jQuery最简单的留言功能^-^
  4. 2019蓝桥杯省赛---java---C---4(质数)
  5. pagerAdapter 与FragmentPagerAdapter的区别
  6. 专属微信二维码python制作_如何利用Python制作简单的公众号二维码关注图
  7. springmvc sends and receives data by ajax request using json format
  8. java并发编程实践(1)intro
  9. java.rmi.UnmarshalException:errorunmarshalling return; java.lang.ClassNotFoundException的解决方法
  10. Mysql优化(三):优化order by