提高效率的 @EnableJdbcAuditing

Table of Contents

@EnableJdbcAuditing 是 Spring Data JDBC 提供的一个注解,用于启用审计功能(Auditing)。它主要负责自动填充实体类中的审计字段,比如 createdBy、createdDate、lastModifiedBy 和 lastModifiedDate。

以下从功能、实现逻辑和源码解析三个方面详细说明。

1. 功能

@EnableJdbcAuditing 提供以下功能:

  • 自动填充创建和修改时间:在插入或更新记录时,自动填充实体类中的时间字段(如 createdDate 和 lastModifiedDate)。
  • 支持用户信息:可以自动填充创建者和修改者信息(如 createdBy 和 lastModifiedBy),需要配合自定义 AuditorAware 实现。

2. 使用示例

  • 数据库表

假设有一张用户表 user:

CREATE TABLE user (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(50),
    created_by VARCHAR(50),
    created_date TIMESTAMP,
    last_modified_by VARCHAR(50),
    last_modified_date TIMESTAMP
);
  • 实体类

定义对应的实体类,标注审计字段:

import org.springframework.data.annotation.CreatedBy;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedBy;
import org.springframework.data.annotation.LastModifiedDate;

import java.time.LocalDateTime;

public class User {
    private Long id;
    private String name;

    @CreatedBy
    private String createdBy;

    @CreatedDate
    private LocalDateTime createdDate;

    @LastModifiedBy
    private String lastModifiedBy;

    @LastModifiedDate
    private LocalDateTime lastModifiedDate;

    // Getters and setters...
}
  • 配置类

使用 @EnableJdbcAuditing 启用审计功能,并实现 AuditorAware 提供用户信息:

import org.springframework.context.annotation.Configuration;
import org.springframework.data.domain.AuditorAware;
import org.springframework.data.jdbc.repository.config.EnableJdbcAuditing;

import java.util.Optional;

@Configuration
@EnableJdbcAuditing
public class AppConfig {

    // Provide the current user information
    @Bean
    public AuditorAware<String> auditorProvider() {
        return () -> Optional.of("system_user"); // Replace with your actual user logic
    }
}
  • Repository

定义 User 的 Repository 接口:

import org.springframework.data.repository.CrudRepository;

public interface UserRepository extends CrudRepository<User, Long> {
}

操作审计

在服务中使用 UserRepository 插入或更新数据时,createdBy、createdDate、lastModifiedBy 和 lastModifiedDate 字段会被自动填充。

3. 实现逻辑和源码解析

核心流程

1. 注册审计功能

@EnableJdbcAuditing 启动时会注册审计相关的组件,如 JdbcAuditingBeanDefinitionRegistrar。

  • 入口类:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(JdbcAuditingRegistrar.class)
public @interface EnableJdbcAuditing {
    // 配置选项
    String auditorAwareRef() default "auditorProvider";
    // 其他属性省略...
}

注解通过 @Import 导入了 JdbcAuditingRegistrar,负责初始化审计配置。

2. 解析审计配置

在 JdbcAuditingRegistrar 中,AuditingHandler 被注册为 Bean。

  • 核心代码:
    class JdbcAuditingRegistrar {
    @Override
    public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry registry) {
        // 注册 AuditingHandler Bean
        BeanDefinitionBuilder auditingHandler = BeanDefinitionBuilder
                .rootBeanDefinition(AuditingHandler.class);
        registry.registerBeanDefinition("auditingHandler", auditingHandler.getBeanDefinition());
    }
    }

3. 处理实体类审计字段

AuditingHandler 负责在持久化前后处理审计字段。

  • 插入时,填充 @CreatedBy 和 @CreatedDate;
  • 更新时,填充 @LastModifiedBy 和 @LastModifiedDate。

4. 用户信息来源

通过 AuditorAware 接口获取当前用户信息:

public interface AuditorAware<T> {
    Optional<T> getCurrentAuditor();
}

@EnableJdbcAuditing 会自动寻找 AuditorAware Bean 并注入 AuditingHandler。

5. 处理时机

在 Spring Data JDBC 的 BeforeSaveCallback 和 BeforeConvertCallback 中调用审计逻辑:
• 插入时:调用 AuditingHandler.markCreated;
• 更新时:调用 AuditingHandler.markModified。

关键源码

以下是 AuditingHandler 的核心方法:

public class AuditingHandler {

    private AuditorAware<?> auditorAware;

    public void markCreated(Object target) {
        Optional<?> auditor = auditorAware.getCurrentAuditor();
        auditor.ifPresent(a -> setField(target, "createdBy", a));
        setField(target, "createdDate", LocalDateTime.now());
    }

    public void markModified(Object target) {
        Optional<?> auditor = auditorAware.getCurrentAuditor();
        auditor.ifPresent(a -> setField(target, "lastModifiedBy", a));
        setField(target, "lastModifiedDate", LocalDateTime.now());
    }

    private void setField(Object target, String fieldName, Object value) {
        // 反射设置字段值
    }
}

4. 总结

@EnableJdbcAuditing 的作用是简化审计功能的实现,结合 Spring Data 的回调机制,自动填充实体的审计字段。它的处理逻辑包括:

  1. 注册审计功能组件(通过 JdbcAuditingRegistrar)。
  2. 在持久化操作中处理审计字段(通过 AuditingHandler)。
  3. 通过 AuditorAware 获取用户信息用于填充字段。

通过 @EnableJdbcAuditing 和少量配置,即可实现高效、自动化的审计功能。

Comments |0|

Legend *) Required fields are marked
**) You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>
Category: 似水流年