日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

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

發(fā)布時間:2023/12/3 javascript 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 spring 自定义日志_Spring和Hibernate的自定义审核日志 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

spring 自定義日志

如果您需要對所有數(shù)據(jù)庫操作進(jìn)行自動審核 ,并且正在使用Hibernate…,則應(yīng)使用Envers或spring data jpa auditing 。 但是,如果由于某些原因您不能使用Envers,則可以使用Hibernate事件偵聽器和spring事務(wù)同步來實現(xiàn)類似的功能。

首先,從事件監(jiān)聽器開始。 您應(yīng)該捕獲所有插入,更新和刪除操作。 但是有一點(diǎn)棘手的問題–如果出于任何原因需要刷新會話,則無法使用傳遞給事件偵聽器的會話直接執(zhí)行該邏輯。 以我為例,我必須獲取一些數(shù)據(jù),然后Hibernate開始向我拋出異常(“ id為null”)。 多個來源確認(rèn)您不應(yīng)在事件偵聽器中與數(shù)據(jù)庫進(jìn)行交互。 因此,您應(yīng)該存儲事件以供以后處理。 您可以將偵聽器注冊為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 –這是一個自定義標(biāo)記注釋(retention = runtime,target = type),您可以將其放置在實體之上。

老實說,我沒有完全了解Envers如何進(jìn)行持久化 ,但是由于我也可以使用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);}} }

除了存儲事件之外,我們還需要存儲執(zhí)行操作的用戶。 為了做到這一點(diǎn),我們需要提供一個方法-參數(shù)級注釋來指定一個參數(shù)。 在我的案例中,注釋稱為AuditLogActor (保留=運(yùn)行時,類型=參數(shù))。

現(xiàn)在剩下的將是處理事件的代碼。 我們想在提交當(dāng)前事務(wù)之前執(zhí)行此操作。 如果事務(wù)在提交時失敗,則審計條目插入也將失敗。 我們通過一點(diǎn)AOP來做到這一點(diǎn):

@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}}

在我的情況下,我不得不注入其他服務(wù),并且spring抱怨相互依賴的bean,所以我改用了applicationContext.getBean(FooBean.class) 。 注意:確保您的方面被spring所捕獲–通過自動掃描,或通過xml / java-config顯式注冊它。

因此,已審核的呼叫將如下所示:

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

總結(jié)一下:Hibernate事件監(jiān)聽器將所有插入,更新和刪除事件存儲為Spring事務(wù)同步資源。 一個方面用spring注冊一個事務(wù)“回調(diào)”,在提交每個事務(wù)之前立即調(diào)用它。 在那里處理所有事件,并插入相應(yīng)的審核日志條目。

這是非常基本的審核日志,可能在收集處理方面存在問題,并且當(dāng)然不能涵蓋所有用例。 但這比手動審核日志處理要好得多,并且在許多系統(tǒng)中,審核日志是強(qiáng)制性功能。

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

spring 自定義日志

總結(jié)

以上是生活随笔為你收集整理的spring 自定义日志_Spring和Hibernate的自定义审核日志的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。