審計
基礎
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 型別的屬性。
提供時間例項的是 org.springframework.data.auditing.DateTimeProvider。預設情況下,這是 CurrentDateTimeProvider。可以透過啟用審計時的 dateTimeProviderRef 屬性來更改此設定,或者透過在 ApplicationContext 中存在專用的 AuditingHandler 或 DateTimeProvider bean 來更改。
審計元資料不一定需要存在於根級實體中,但可以新增到嵌入式實體中(取決於實際使用的儲存),如下面的程式碼片段所示。
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 帶有一個實體監聽器,可以用來觸發審計資訊的捕獲。首先,你必須在你的 orm.xml 檔案中註冊 AuditingEntityListener,以便在你的持久化上下文中用於所有實體,如以下示例所示
<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 屬性來選擇要使用的實現。