Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/spring-boot/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 有没有一种方法可以选择性地禁用对测试中实体修改的审核?_Java_Spring Boot_Jpa_Spring Data Jpa_Auditing - Fatal编程技术网

Java 有没有一种方法可以选择性地禁用对测试中实体修改的审核?

Java 有没有一种方法可以选择性地禁用对测试中实体修改的审核?,java,spring-boot,jpa,spring-data-jpa,auditing,Java,Spring Boot,Jpa,Spring Data Jpa,Auditing,我有几个实体需要审计。审计是通过使用以下JPA事件侦听器实现的 public class AuditListener { @PrePersist @Transactional(readOnly = true, propagation = Propagation.REQUIRES_NEW) public void setCreatedOn(Auditable auditable) { User currentUser = getCurrentUser();

我有几个实体需要审计。审计是通过使用以下JPA事件侦听器实现的

public class AuditListener {

    @PrePersist
    @Transactional(readOnly = true, propagation = Propagation.REQUIRES_NEW)
    public void setCreatedOn(Auditable auditable) {
        User currentUser = getCurrentUser();
        Long entityId = auditable.getId();
        Audit audit;

        if (isNull(entityId)) {
            audit = getCreatedOnAudit(currentUser);
        } else {
            audit = getUpdatedOnAudit(auditable, currentUser);
        }

        auditable.setAudit(audit);
    }

    @PreUpdate
    @Transactional(readOnly = true, propagation = Propagation.REQUIRES_NEW)
    public void setUpdatedOn(Auditable auditable) {
        User currentUser = getCurrentUser();
        auditable.setAudit(getUpdatedOnAudit(auditable, currentUser));
    }

    private Audit getCreatedOnAudit(User currentUser) {
        return Audit.builder()
                .userCreate(currentUser)
                .dateCreate(now())
                .build();
    }

    private Audit getUpdatedOnAudit(Auditable auditable, User currentUser) {
        AuditService auditService = BeanUtils.getBean(AuditService.class);
        Audit audit = auditService.getAudit(auditable.getClass().getName(), auditable.getId());
        audit.setUserUpdate(currentUser);
        audit.setDateUpdate(now());
        return audit;
    }

    private User getCurrentUser() {
        String userName = "admin";
        UserService userService = BeanUtils.getBean(UserService.class);
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        if (nonNull(auth)) {
            Object principal = auth.getPrincipal();
            if (principal instanceof UserDetails) {
                userName = ((UserDetails)principal).getUsername();
            }
        }
        return userService.findByLogin(userName);
    }
}
在一些测试的测试环境(单元测试,e2e)中,我希望能够手动设置审计

可能吗?我以前曾尝试用SpringAOP解决这个问题,但不幸的是没有成功。我认为,Spring AOP可以通过在切入点中使用各种组合来有选择地设置审计:

有没有一种方法可以通过使用JPA功能选择性地设置审核?

如所述解决

pre persist和pre update的逻辑被移动到一个单独的可注入组件,并且
AuditListener
将执行委托给该组件的不同实现,具体取决于当前的活动配置文件

对于Spring Boot 2.1.0:

通用接口:

public interface AuditManager {

    void performPrePersistLogic(Auditable auditable);

    void performPreUpdateLogic(Auditable auditable);
}
JPA回调的侦听器:

@Component
@RequiredArgsConstructor
public class AuditListener {

    private final AuditManager auditManager;

    @PrePersist
    public void setCreatedOn(Auditable auditable) {
        auditManager.performPrePersistLogic(auditable);
    }

    @PreUpdate
    public void setUpdatedOn(Auditable auditable) {
        auditManager.performPreUpdateLogic(auditable);
    }
}
测试环境和本地环境的公共接口实现:

@RequiredArgsConstructor
public class AuditChanger implements AuditManager {

    private final UserService userService;
    private final AuditService auditService;

    @Override
    @Transactional(readOnly = true, propagation = Propagation.REQUIRES_NEW)
    public void performPrePersistLogic(Auditable auditable) {
        // logic here
    }

    @Override
    @Transactional(readOnly = true, propagation = Propagation.REQUIRES_NEW)
    public void performPreUpdateLogic(Auditable auditable) {
        // logic here        
    }   
}

public class AuditNoChanger implements AuditManager {

// mostly similar

...
允许Spring根据当前活动的配置文件执行不同实现的注入的配置:

@Configuration
public class AuditConfig {

    @Bean
    @Profile("e2e")
    public AuditManager getAuditNoChanger() {
        return new AuditNoChanger();
    }

    @Bean
    @Profile("local")
    public AuditManager getAuditChanger(AuditService auditService, 
            CurrentUserService currentUserService) {
        return new AuditChanger(auditService, currentUserService);
    }
}
还需要允许在*.yml文件中重写bean:

spring:
  main:
    allow-bean-definition-overriding: true
由…解决

pre persist和pre update的逻辑被移动到一个单独的可注入组件,并且
AuditListener
将执行委托给该组件的不同实现,具体取决于当前的活动配置文件

对于Spring Boot 2.1.0:

通用接口:

public interface AuditManager {

    void performPrePersistLogic(Auditable auditable);

    void performPreUpdateLogic(Auditable auditable);
}
JPA回调的侦听器:

@Component
@RequiredArgsConstructor
public class AuditListener {

    private final AuditManager auditManager;

    @PrePersist
    public void setCreatedOn(Auditable auditable) {
        auditManager.performPrePersistLogic(auditable);
    }

    @PreUpdate
    public void setUpdatedOn(Auditable auditable) {
        auditManager.performPreUpdateLogic(auditable);
    }
}
测试环境和本地环境的公共接口实现:

@RequiredArgsConstructor
public class AuditChanger implements AuditManager {

    private final UserService userService;
    private final AuditService auditService;

    @Override
    @Transactional(readOnly = true, propagation = Propagation.REQUIRES_NEW)
    public void performPrePersistLogic(Auditable auditable) {
        // logic here
    }

    @Override
    @Transactional(readOnly = true, propagation = Propagation.REQUIRES_NEW)
    public void performPreUpdateLogic(Auditable auditable) {
        // logic here        
    }   
}

public class AuditNoChanger implements AuditManager {

// mostly similar

...
允许Spring根据当前活动的配置文件执行不同实现的注入的配置:

@Configuration
public class AuditConfig {

    @Bean
    @Profile("e2e")
    public AuditManager getAuditNoChanger() {
        return new AuditNoChanger();
    }

    @Bean
    @Profile("local")
    public AuditManager getAuditChanger(AuditService auditService, 
            CurrentUserService currentUserService) {
        return new AuditChanger(auditService, currentUserService);
    }
}
还需要允许在*.yml文件中重写bean:

spring:
  main:
    allow-bean-definition-overriding: true

简单地模拟/监视
UserService
(对测试上下文使用
@MockBean
或简单的bean定义覆盖)怎么样?您应该能够以类似的方式覆盖创建/修改时间,使用
now(clock)
而不是
now()
,并注入
clock
,然后使用模拟/固定瞬间覆盖测试的提供程序定义。顺便说一句,您不需要
BeanUtils.getBean(UserService.class)
,Spring在JPA listenersHow中支持依赖项注入,简单地模拟/监视
UserService
(使用
@MockBean
或测试上下文的简单bean定义覆盖)?您应该能够以类似的方式覆盖创建/修改时间,使用
now(clock)
而不是
now()
,并注入
clock
,然后使用模拟/固定瞬间覆盖测试的提供程序定义。顺便说一句,您不需要
BeanUtils.getBean(UserService.class)
,Spring支持JPA侦听器中的依赖注入