You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Spring Boot+MongoDB中自动填充CreatedBy与LastModifiedBy字段

利用Spring Data MongoDB审计机制自动填充用户字段

你完全可以借助Spring Data MongoDB的审计扩展来自动填充CreatedBy和LastModifiedBy字段,不用在服务层手动编写重复代码,具体实现步骤如下:

1. 实现AuditorAware接口

创建一个类实现AuditorAware,用来提供当前操作的用户ID,这个类会被Spring自动调用以填充审计字段:

@Component
public class SpringSecurityAuditorAware implements AuditorAware<String> {

    @Override
    public Optional<String> getCurrentAuditor() {
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        
        // 处理未登录或匿名用户的情况,可根据业务需求调整逻辑
        if (auth == null || !auth.isAuthenticated() || auth instanceof AnonymousAuthenticationToken) {
            return Optional.empty();
        }

        // 假设你的Authentication中存储的是User对象(已实现UserDetails)
        User currentUser = (User) auth.getPrincipal();
        return Optional.of(currentUser.getId());
        
        // 如果Authentication中只有用户名,需查询用户ID的话,可注入UserRepository:
        // String username = auth.getName();
        // return userRepository.findByUsername(username)
        //         .map(User::getId);
    }
}

2. 启用Mongo审计并指定AuditorBean

在Spring Boot启动类上,修改@EnableMongoAuditing注解,指定刚才实现的AuditorAware bean:

@SpringBootApplication
@EnableMongoAuditing(auditorAwareRef = "springSecurityAuditorAware")
public class YourApplication {
    public static void main(String[] args) {
        SpringApplication.run(YourApplication.class, args);
    }
}

3. 在实体类中添加审计注解

在Project实体的对应字段上添加@CreatedBy和@LastModifiedBy注解,配合已有的日期审计注解:

@Document(collection = "projects")
public class Project {
    // 其他字段...

    @CreatedBy
    private String createdBy;

    @LastModifiedBy
    private String lastModifiedBy;

    @CreatedDate
    private LocalDateTime createdDate;

    @LastModifiedDate
    private LocalDateTime lastModifiedDate;

    // 建议把active字段的默认值放到实体类中,避免在服务层重复设置
    private boolean active = true;

    // getter、setter...
}

4. 简化服务层代码

现在可以去掉服务层中手动设置createdBy和lastModifiedBy的代码,方法会变得更简洁:

public Project create(Project project) {
    getByName(project.getName()).ifPresent(existing -> {
        throw new ProjectAlreadyExistsException(existing.getName());
    });

    // 无需手动设置createdBy、lastModifiedBy,审计机制会自动处理
    return projectRepository.save(project);
}

额外说明

  • 这种方式遵循关注点分离原则,把审计逻辑统一封装到AuditorAware中,所有需要审计的实体都能复用这套逻辑,避免重复代码。
  • 如果涉及异步方法,需要确保SecurityContext能传递到异步线程中,可以在配置类中设置:
    @Configuration
    public class AsyncConfig implements AsyncConfigurer {
        @Override
        public Executor getAsyncExecutor() {
            ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
            executor.setTaskDecorator(runnable -> {
                Authentication auth = SecurityContextHolder.getContext().getAuthentication();
                return () -> {
                    try {
                        SecurityContextHolder.getContext().setAuthentication(auth);
                        runnable.run();
                    } finally {
                        SecurityContextHolder.clearContext();
                    }
                };
            });
            executor.initialize();
            return executor;
        }
    }
    

内容的提问来源于stack exchange,提问作者Aymen Maamri

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 15:33:33