javascript
spring 自定义日志_Spring和Hibernate的自定义审核日志
spring 自定義日志
如果您需要對所有數據庫操作進行自動審核 ,并且正在使用Hibernate…,則應使用Envers或spring data jpa auditing 。 但是,如果由于某些原因您不能使用Envers,則可以使用Hibernate事件偵聽器和spring事務同步來實現類似的功能。
首先,從事件監聽器開始。 您應該捕獲所有插入,更新和刪除操作。 但是有一點棘手的問題–如果出于任何原因需要刷新會話,則無法使用傳遞給事件偵聽器的會話直接執行該邏輯。 以我為例,我必須獲取一些數據,然后Hibernate開始向我拋出異常(“ 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) { .. }總結一下:Hibernate事件監聽器將所有插入,更新和刪除事件存儲為Spring事務同步資源。 一個方面用spring注冊一個事務“回調”,在提交每個事務之前立即調用它。 在那里處理所有事件,并插入相應的審核日志條目。
這是非常基本的審核日志,可能在收集處理方面存在問題,并且當然不能涵蓋所有用例。 但這比手動審核日志處理要好得多,并且在許多系統中,審核日志是強制性功能。
翻譯自: https://www.javacodegeeks.com/2016/07/custom-audit-log-spring-hibernate.html
spring 自定義日志
總結
以上是生活随笔為你收集整理的spring 自定义日志_Spring和Hibernate的自定义审核日志的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: functor_纯Java中的Funct
- 下一篇: 机器学习java_如何开始使用Java机