General Auditing Configuration

Auditing

Basics

Spring Data 提供复杂的支持,以透明地跟踪谁创建或更改了实体以及更改发生的时间。要从该功能中受益,你必须使用可以通过注释定义或通过实现接口来定义的审核元数据来装备实体类。此外,还必须通过注释配置或 XML 配置启用审核,以注册所需的架构组件。请参阅特定于存储的章节以获取配置示例。

Spring Data provides sophisticated support to transparently keep track of who created or changed an entity and when the change happened.To benefit from that functionality, you have to equip your entity classes with auditing metadata that can be defined either using annotations or by implementing an interface. Additionally, auditing has to be enabled either through Annotation configuration or XML configuration to register the required infrastructure components. Please refer to the store-specific section for configuration samples.

仅跟踪创建和修改日期的应用程序不需要使其实体类实现 <<`AuditorAware`,审核.审核感知>>。

Applications that only track creation and modification dates are not required do make their entities implement <<`AuditorAware`,auditing.auditor-aware>>.

Annotation-based Auditing Metadata

我们提供 @CreatedBy@LastModifiedBy 来捕获创建或修改实体的用户,以及 @CreatedDate@LastModifiedDate 来捕获更改发生的时间。

We provide @CreatedBy and @LastModifiedBy to capture the user who created or modified the entity as well as @CreatedDate and @LastModifiedDate to capture when the change happened.

An audited entity
class Customer {

  @CreatedBy
  private User user;

  @CreatedDate
  private Instant createdDate;

  // … further properties omitted
}

如你所见,可以有选择地应用注释,具体取决于你想要捕获的信息。用于指示何时进行更改的注释可用于 JDK8 日期和时间类型、longLong 以及旧版 Java DateCalendar 类型的属性。

As you can see, the annotations can be applied selectively, depending on which information you want to capture. The annotations, indicating to capture when changes are made, can be used on properties of type JDK8 date and time types, long, Long, and legacy Java Date and Calendar.

审核元数据不一定需要存在于根级实体中,但可以添加到嵌入式实体中(具体取决于实际使用的存储),如下面的代码段所示。

Auditing metadata does not necessarily need to live in the root level entity but can be added to an embedded one (depending on the actual store in use), as shown in the snippet below.

Audit metadata in embedded entity
class Customer {

  private AuditMetadata auditingMetadata;

  // … further properties omitted
}

class AuditMetadata {

  @CreatedBy
  private User user;

  @CreatedDate
  private Instant createdDate;

}

Interface-based Auditing Metadata

如果你不想使用注释来定义审核元数据,你可以让你的域类实现 Auditable 接口。它公开了所有审核属性的 setter 方法。

In case you do not want to use annotations to define auditing metadata, you can let your domain class implement the Auditable interface. It exposes setter methods for all of the auditing properties.

AuditorAware

如果你使用 @CreatedBy@LastModifiedBy,则审核基础设施在某种程度上需要知道当前主体。为此,我们提供了 AuditorAware<T> SPI 接口,你必须实现该接口才能告诉基础设施与应用程序交互的当前用户或系统是谁。泛型类型 T 定义了用 @CreatedBy@LastModifiedBy 注释的属性必须是什么类型。

In case you use either @CreatedBy or @LastModifiedBy, the auditing infrastructure somehow needs to become aware of the current principal. To do so, we provide an AuditorAware<T> SPI interface that you have to implement to tell the infrastructure who the current user or system interacting with the application is. The generic type T defines what type the properties annotated with @CreatedBy or @LastModifiedBy have to be.

以下示例显示了一个使用 Spring Security 的 Authentication 对象的接口实现:

The following example shows an implementation of the interface that uses Spring Security’s Authentication object:

Implementation of AuditorAware based on Spring Security
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,你也可以从任何地方查找它。

The implementation accesses the Authentication object provided by Spring Security and looks up the custom UserDetails instance that you have created in your UserDetailsService implementation. We assume here that you are exposing the domain user through the UserDetails implementation but that, based on the Authentication found, you could also look it up from anywhere.

ReactiveAuditorAware

在使用响应式基础设施时,你可能希望利用上下文信息来提供 @CreatedBy@LastModifiedBy 信息。我们提供了 ReactiveAuditorAware<T> SPI 接口,你必须实现该接口才能告诉基础设施与应用程序交互的当前用户或系统是谁。泛型类型 T 定义了用 @CreatedBy@LastModifiedBy 注释的属性必须是什么类型。

When using reactive infrastructure you might want to make use of contextual information to provide @CreatedBy or @LastModifiedBy information. We provide an ReactiveAuditorAware<T> SPI interface that you have to implement to tell the infrastructure who the current user or system interacting with the application is. The generic type T defines what type the properties annotated with @CreatedBy or @LastModifiedBy have to be.

以下示例显示了一个使用 Spring Security 响应式 Authentication 对象的接口实现:

The following example shows an implementation of the interface that uses reactive Spring Security’s Authentication object:

Implementation of ReactiveAuditorAware based on Spring Security
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,你也可以从任何地方查找它。

The implementation accesses the Authentication object provided by Spring Security and looks up the custom UserDetails instance that you have created in your UserDetailsService implementation. We assume here that you are exposing the domain user through the UserDetails implementation but that, based on the Authentication found, you could also look it up from anywhere.

这里还提供了一个便捷的基类 AbstractAuditable,您可以对其进行扩展以避免手动实现接口方法的需要。这样做会增加您的领域类与 Spring Data 的耦合度,这可能是您希望避免的事情。通常,基于注释的方式来定义审计元数据是首选,因为它侵入性更小、灵活性更高。

There is also a convenience base class, AbstractAuditable, which you can extend to avoid the need to manually implement the interface methods. Doing so increases the coupling of your domain classes to Spring Data, which might be something you want to avoid. Usually, the annotation-based way of defining auditing metadata is preferred as it is less invasive and more flexible.

General Auditing Configuration

Spring Data JPA 附带一个实体监听器,可用于触发审计信息的捕获。首先,您必须注册 AuditingEntityListener,以便在您的 orm.xml 文件中用于您的持久化上下文中的所有实体,如下例所示:

Spring Data JPA ships with an entity listener that can be used to trigger the capturing of auditing information. First, you must register the AuditingEntityListener to be used for all entities in your persistence contexts inside your orm.xml file, as shown in the following example:

Example 1. Auditing configuration 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>

您还可以逐个实体启用 AuditingEntityListener,方法是使用 @EntityListeners 注解,如下所示:

You can also enable the AuditingEntityListener on a per-entity basis by using the @EntityListeners annotation, as follows:

@Entity
@EntityListeners(AuditingEntityListener.class)
public class MyEntity {

}

审计功能需要 spring-aspects.jar 在类路径上。

The auditing feature requires spring-aspects.jar to be on the classpath.

适当地修改 orm.xml,并在类路径中包含 spring-aspects.jar,那么激活审计功能就是向您的配置添加 Spring Data JPA auditing 命名空间元素,如下所示:

With orm.xml suitably modified and spring-aspects.jar on the classpath, activating auditing functionality is a matter of adding the Spring Data JPA auditing namespace element to your configuration, as follows:

Example 2. Activating auditing using XML configuration
<jpa:auditing auditor-aware-ref="yourAuditorAwareBean" />

从 Spring Data JPA 1.5 开始,您可以通过使用 @EnableJpaAuditing 注解对一个配置类进行注释来启用审计。您仍必须修改 orm.xml 文件,并在类路径中包含 spring-aspects.jar。以下示例演示了如何使用 @EnableJpaAuditing 注解:

As of Spring Data JPA 1.5, you can enable auditing by annotating a configuration class with the @EnableJpaAuditing annotation. You must still modify the orm.xml file and have spring-aspects.jar on the classpath. The following example shows how to use the @EnableJpaAuditing annotation:

Example 3. Activating auditing with Java configuration
@Configuration
@EnableJpaAuditing
class Config {

  @Bean
  public AuditorAware<AuditableUser> auditorProvider() {
    return new AuditorAwareImpl();
  }
}

如果您向 ApplicationContext 公开类型为 AuditorAware 的 bean,则审计基础架构会自动选择它并使用它来确定要设置在域类型上的当前用户。如果您在 ApplicationContext 中注册了多个实现,则可以通过显式设置 @EnableJpaAuditingauditorAwareRef 属性来选择要使用的实现。

If you expose a bean of type AuditorAware to the ApplicationContext, the auditing infrastructure automatically picks it up and uses it to determine the current user to be set on domain types. If you have multiple implementations registered in the ApplicationContext, you can select the one to be used by explicitly setting the auditorAwareRef attribute of @EnableJpaAuditing.