稽核
基礎
Spring Data 提供精密的支援,以透明地追蹤誰建立或變更了實體,以及變更發生的時間。為了從該功能中獲益,您必須為您的實體類別配備稽核中繼資料,這些中繼資料可以使用註解或實作介面來定義。此外,必須透過註解組態或 XML 組態啟用稽核,以註冊所需的基础架構元件。請參閱特定儲存區章節以取得組態範例。
僅追蹤建立和修改日期的應用程式不需要使其應用程式實作 |
基於註解的稽核中繼資料
我們提供 @CreatedBy
和 @LastModifiedBy
來捕捉建立或修改實體的使用者,以及 @CreatedDate
和 @LastModifiedDate
來捕捉變更發生的時間。
class Customer {
@CreatedBy
private User user;
@CreatedDate
private Instant createdDate;
// … further properties omitted
}
如您所見,註解可以選擇性地應用,具體取決於您要捕捉的資訊。指示捕捉變更時間的註解可以用於 JDK8 日期和時間類型、long
、Long
和舊版 Java Date
和 Calendar
類型的屬性。
稽核中繼資料不一定需要存在於根層級實體中,但可以新增至嵌入式實體(取決於實際使用的儲存區),如下面的程式碼片段所示。
class Customer {
private AuditMetadata auditingMetadata;
// … further properties omitted
}
class AuditMetadata {
@CreatedBy
private User user;
@CreatedDate
private Instant createdDate;
}
AuditorAware
如果您使用 @CreatedBy
或 @LastModifiedBy
,稽核基礎架構需要以某種方式知道當前的委託人。為此,我們提供了一個 AuditorAware<T>
SPI 介面,您必須實作該介面以告知基礎架構誰是目前與應用程式互動的使用者或系統。泛型類型 T
定義了以 @CreatedBy
或 @LastModifiedBy
註解的屬性必須是什麼類型。
以下範例顯示了介面的實作,該實作使用 Spring Security 的 Authentication
物件
AuditorAware
實作class SpringSecurityAuditorAware implements AuditorAware<User> {
@Override
public Optional<User> getCurrentAuditor() {
return Optional.ofNullable(SecurityContextHolder.getContext())
.map(SecurityContext::getAuthentication)
.filter(Authentication::isAuthenticated)
.map(Authentication::getPrincipal)
.map(User.class::cast);
}
}
該實作存取 Spring Security 提供的 Authentication
物件,並查找您在 UserDetailsService
實作中建立的自訂 UserDetails
實例。我們在此假設您透過 UserDetails
實作公開網域使用者,但根據找到的 Authentication
,您也可以從任何地方查找它。
ReactiveAuditorAware
當使用反應式基礎架構時,您可能想要使用上下文資訊來提供 @CreatedBy
或 @LastModifiedBy
資訊。我們提供了一個 ReactiveAuditorAware<T>
SPI 介面,您必須實作該介面以告知基礎架構誰是目前與應用程式互動的使用者或系統。泛型類型 T
定義了以 @CreatedBy
或 @LastModifiedBy
註解的屬性必須是什麼類型。
以下範例顯示了介面的實作,該實作使用反應式 Spring Security 的 Authentication
物件
ReactiveAuditorAware
實作class SpringSecurityAuditorAware implements ReactiveAuditorAware<User> {
@Override
public Mono<User> getCurrentAuditor() {
return ReactiveSecurityContextHolder.getContext()
.map(SecurityContext::getAuthentication)
.filter(Authentication::isAuthenticated)
.map(Authentication::getPrincipal)
.map(User.class::cast);
}
}
該實作存取 Spring Security 提供的 Authentication
物件,並查找您在 UserDetailsService
實作中建立的自訂 UserDetails
實例。我們在此假設您透過 UserDetails
實作公開網域使用者,但根據找到的 Authentication
,您也可以從任何地方查找它。
還有一個方便的基底類別 AbstractAuditable
,您可以擴充它以避免手動實作介面方法的需要。這樣做會增加您的網域類別與 Spring Data 的耦合,這可能是您想要避免的。通常,基於註解的定義稽核中繼資料的方式是首選,因為它侵入性較小且更靈活。
通用稽核組態
Spring Data JPA 隨附一個實體監聽器,可用於觸發稽核資訊的捕捉。首先,您必須註冊 AuditingEntityListener
,以便在您的 orm.xml
檔案中用於持久化上下文中的所有實體,如下例所示
<persistence-unit-metadata>
<persistence-unit-defaults>
<entity-listeners>
<entity-listener class="….data.jpa.domain.support.AuditingEntityListener" />
</entity-listeners>
</persistence-unit-defaults>
</persistence-unit-metadata>
您也可以使用 @EntityListeners
註解在每個實體的基礎上啟用 AuditingEntityListener
,如下所示
@Entity
@EntityListeners(AuditingEntityListener.class)
public class MyEntity {
}
稽核功能需要 spring-aspects.jar 在類別路徑上。 |
在適當修改 orm.xml
且 spring-aspects.jar
在類別路徑上的情況下,啟用稽核功能只需將 Spring Data JPA auditing
命名空間元素新增至您的組態即可,如下所示
<jpa:auditing auditor-aware-ref="yourAuditorAwareBean" />
從 Spring Data JPA 1.5 開始,您可以透過使用 @EnableJpaAuditing
註解註解組態類別來啟用稽核。您仍然必須修改 orm.xml
檔案並讓 spring-aspects.jar
在類別路徑上。以下範例示範如何使用 @EnableJpaAuditing
註解
@Configuration
@EnableJpaAuditing
class Config {
@Bean
public AuditorAware<AuditableUser> auditorProvider() {
return new AuditorAwareImpl();
}
}
如果您向 ApplicationContext
公開類型為 AuditorAware
的 bean,則稽核基礎架構會自動拾取它並使用它來確定要設定在網域類型上的當前使用者。如果您在 ApplicationContext
中註冊了多個實作,您可以透過顯式設定 @EnableJpaAuditing
的 auditorAwareRef
屬性來選擇要使用的實作。