我有一个已知的值,它在某个时间戳之前是有效的,此时它将过期,不应再使用。这是一个使用googleguava库的javaspring启动应用程序。
我用一个带有过期时间戳的简单 Package 器实现了这一点。
import java.time.Clock;
import java.time.Instant;
import java.util.Objects;
import java.util.Optional;
public class ExpiringValue<T> {
private final T value;
private final Instant expiresAt;
private final Clock clock;
public ExpiringValue(T value, Instant expiresAt) {
this(value, expiresAt, Clock.systemDefaultZone());
}
public ExpiringValue(T value, Instant expiresAt, Clock clock) {
this.value = Objects.requireNonNull(value);
this.expiresAt = Objects.requireNonNull(expiresAt);
this.clock = Objects.requireNonNull(clock);
}
public Optional<T> get() {
return isExpired() ? Optional.empty() : Optional.ofNullable(value);
}
private boolean isExpired() {
return !Instant.now(clock).isBefore(expiresAt);
}
}
private static void testExpires(Object value, Instant expiresAt) {
ExpiringValue<Object> expiringValue = new ExpiringValue<>(value, expiresAt);
// Time passes...
expiringValue.get().orElseThrow(() -> new RuntimeException("Value is no longer valid"));
}
这就是说,这感觉像是足够常见的功能,我可能是重新发明车轮这样做。我找到Guava了 Suppliers.memoizeWithExpiration
. 但是,这更多地是围绕生成值的实际函数设计的,因此需要一些限制,才能使它与已经存在的值一起工作。它也不允许通过一个 Clock
,这意味着对使用该功能的代码进行更高级别的自动化测试不能仅仅手动更新时钟,以验证是否按预期发生了过期。
private static void testExpires(Object value, Instant expiresAt) {
Instant now = Instant.now();
if (!expiresAt.isAfter(now)) {
throw new RuntimeException("Value is no longer valid");
}
AtomicBoolean supplied = new AtomicBoolean(false);
Supplier<Object> expiringValue = Suppliers.memoizeWithExpiration(() -> {
if (supplied.getAndSet(true)) {
throw new RuntimeException("Value is no longer valid");
} else {
return value;
}
}, Duration.between(now, expiresAt).toNanos(), TimeUnit.NANOSECONDS);
expiringValue.get(); // Start the countdown
// Time passes...
expiringValue.get();
}
有没有比自己实现更直接的方法来实现这个目标?
暂无答案!
目前还没有任何答案,快来回答吧!