我怎样才能使代码更具反应性;删除 if's,检查是否为空并进行中间日志记录

How can I make code more reactive; Remove if's, check for empty and do intermediate logging

我正在考虑如何以更具反应性的方式重写此代码(没有 if,在中间步骤中抛出异常等,以及记录中间结果的最佳实践)

        return identityRepository.findByDeviceIdAndToken(
                deviceId,
                authToken
        ).doOnSuccess(identity -> {
            if (identity == null) {
                log.info(
                        "Pair Auth-Token: {} and Device-ID: {} not found",
                        authToken,
                        deviceId
                );
            }
        })
                .map(MyPrincipal::new)
                .map(
                        principal -> {
                            if (!principal.isCredentialsNonExpired()) {
                                throw new CredentialsExpiredException();
                            }
                            return 
                                    new UsernamePasswordAuthenticationToken(
                                            principal,
                                            null,
                                            Collections.emptyList()
                                    )
                            ;
                        }
                )
                .flatMap(this.authenticationManager::authenticate)
                .map(SecurityContextImpl::new);

您可以这样更改地图逻辑:

return identityRepository.findByDeviceIdAndToken(
                deviceId,
                authToken
        ).doOnSuccess(identity -> {
            if (identity == null) {
                log.info(
                        "Pair Auth-Token: {} and Device-ID: {} not found",
                        authToken,
                        deviceId
                );
            }
        })
                .map(MyPrincipal::new)
                .filter(principal -> principal.isCredentialsNonExpired())
                .switchIfEmpty(Mono.error(new CredentialsExpiredException()))
                .map(x -> new UsernamePasswordAuthenticationToken(
                                principal,
                                null,
                                Collections.emptyList()
                        )
                )
                .flatMap(this.authenticationManager::authenticate)
                .map(SecurityContextImpl::new);

您可以使用 Optional 从代码中消除 if 条件。您的代码中总共有 2 个 if 条件。 让我们首先从 doOnSuccess 方法

中删除 if
.doOnSuccess(identity -> {
 if (identity == null) {
  log.info(
   "Pair Auth-Token: {} and Device-ID: {} not found",
   authToken,
   deviceId
  );
 }
})

您可以使用 ifPresentOrElse 删除 if 条件。它是在 java 9:

中引入的
.doOnSuccess(identity -> Optional.ofNullable(identity)
 .ifPresentOrElse(
  val -> {},
  () -> log.info(
   "Pair Auth-Token: {} and Device-ID: {} not found",
   authToken,
   deviceId)
 )
)

第二个if条件在map方法中

.map(principal -> {
    if (!principal.isCredentialsNonExpired()) {
        throw new CredentialsExpiredException();
    }
    return new UsernamePasswordAuthenticationToken(principal, null, Collections.emptyList());
})

在上面的代码中,您根据条件抛出一些异常。如果 Optional 由于过滤器而变为空,您可以使用 filter along with orElseThrow 抛出异常:

.map(principal -> Optional.of(new UsernamePasswordAuthenticationToken(principal, null, Collections.emptyList()))
        .filter(token -> token.getPrincipal().isCredentialsNonExpired())
        .orElseThrow(CredentialsExpiredException::new))