有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java向@CreatedBy添加更多信息

我有一个SpringBoot2.3应用程序。“所有我的实体”扩展了一个abtract实体,该实体具有一些审核字段,如:

@CreatedBy
@Column(updatable = false)
protected String createdBy;

@CreatedDate
@Column(nullable = false, updatable = false)
protected Instant createdDate;

我实现了AuditorAware

public class SpringSecurityAuditorAware implements AuditorAware<String> {

    public static final String SYSTEM_USER = "system";

    @Override
    public Optional<String> getCurrentAuditor() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

        if (authentication == null || !authentication.isAuthenticated()) {
            return Optional.of(SYSTEM_USER);
        }

        Object principal = authentication.getPrincipal();

        /**
         * If the principal is a CustomUserDetail I access to the name property
         */
        if (principal instanceof CustomUserDetail) {
            CustomUserDetail user = (CustomUserDetail) principal;
            // the sid of the user if not null or the username instead
            String sid = user.getSid() != null ? user.getSid() : user.getUsername();
            return Optional.ofNullable(sid);
        }

        return Optional.of(authentication.getName());
    }
}

createdBy字段中,我保存用户的sid(标识符)。这样,我就有了对源表的引用,并且可以在所有更改和用户之间保持链接。 但是,出于性能原因,我还想在每个实体中保存用户的全名。 有没有一个干净的方法来达到这个目标?我能想到的唯一一件事就是使用EntityListener并将createdByName设置在@PrePersist

@Component
public class MyEntityListener { 

 @PrePersist
 private void onPrePersist(MyAbstractEntity entity) {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

        if (authentication != null) {
              Object principal = authentication.getPrincipal();
              if (principal instanceof CustomUserDetail) {
                    CustomUserDetail user = (CustomUserDetail) principal;
                    entity.setCreatedByName(user.getFullName());
              }
        }
 }
}

你觉得怎么样?您还有其他更好/干净的方法吗


共 (1) 个答案

  1. # 1 楼答案

    注释为@CreatedBy的字段可以是任何类型。我认为一种方法可以是创建一个AuditUser类,该类包含像userIduserFullName这样的字段,并将其注释为@Embeddable(在这种情况下,也可以使用@AttributeOverrides来声明表列的命名方式)。然后,在实体中,可以有一个AuditUser字段,用@CreatedBy@Embedded注释,并结合AuditorAware<AuditUser>的实现。有关此blog post(Baeldung)中可嵌入对象的更多信息

    如果您需要更具体的东西,您可以考虑创建一些定制的东西,灵感来自Spring如何实现JPA审计(查看类AuditingEntityListenerAuditingHandlerAnnotationAuditingMetadata