Java @可缓存和@计划在Spring引导应用程序中同时启动
前言:在一个产品(一组spring boot应用程序)中,我的工作是使用JWT令牌进行安全保护,从内部服务器获取,并使用它通过REST调用在服务之间进行通信 问题:JWT令牌TTL精确到2小时,因此我尝试将其放入缓存中,以便对于给定的Java @可缓存和@计划在Spring引导应用程序中同时启动,java,spring-boot,caching,jwt,scheduling,Java,Spring Boot,Caching,Jwt,Scheduling,前言:在一个产品(一组spring boot应用程序)中,我的工作是使用JWT令牌进行安全保护,从内部服务器获取,并使用它通过REST调用在服务之间进行通信 问题:JWT令牌TTL精确到2小时,因此我尝试将其放入缓存中,以便对于给定的用户ID,我不应该在到期之前从服务器获取新的JWT令牌。这部分工作正常,问题是在TTL过期时退出缓存 代码如下 import org.springframework.cache.annotation.CacheEvict; import org.springfram
用户ID
,我不应该在到期之前从服务器获取新的JWT令牌。这部分工作正常,问题是在TTL过期时退出缓存
代码如下
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.scheduling.annotation.Scheduled;
public class JWTUtility {
// Some Fake JWT Ticket
private static final String FAKE_JWT_TICKET = "";
@Cacheable(value = "jwtToken", key = "#userId", condition = "#userId != null")
public String getToken(boolean securityEnabled, String userId) {
if (!securityEnabled) {
return FAKE_JWT_TICKET;
} else {
// Proper logic to fetch and return the JWT token from Server
// Assume this works
}
}
// JWT Ticket TTL is 2 Hrs, scheduling cache evict at 1:50 Hrs
@Scheduled(fixedRate = 6600000)
@CacheEvict(value = "jwtToken", allEntries = true)
public void evictJWTTicketValues() {
//Intentionally left blank
}
}
日程安排部分没有像我期望的那样工作。问题是当某个特定
userId
的JWT票证进入缓存jwtToken
时,如何启动调度程序的计时器。我愿意为上述JWTUtility
类完全重构/重写逻辑。正如@Thomas Kåsene指出的那样-如果您可以使用其他缓存提供程序,那么您可以在配置缓存时设置逐出策略。以下是配置的示例:
您需要声明并将您的方法注释为-
@Cacheable(cacheNames = "jwtTokenCache", value = "jwtToken", key = "#userId", condition = "#userId != null")
如果您愿意使用SpringCache中默认的缓存提供程序以外的其他缓存提供程序(我相信这是内存中的HashMap),您可以在例如ehCache中设置逐出策略。不过,就我个人而言,我已经停止尝试使用Spring缓存来实现这一点,而只是从包含令牌及其到期日的映射中获取令牌。然后,我可以检查我是否需要检索一个新的。顺便说一下,如果你考虑每2小时左右删除整个事情,也可以考虑每2个小时,你可能会在平均响应时间上跳一跳,并给令牌提供者一个新的调用。这可能是个问题,也可能不是,但值得一提。您还会注意到,刚刚发行的代币有时会被丢弃,因为它们是在缓存被逐出之前发行的。@Thomas Kåsene,感谢您的见解。1.我第一次想到使用一个简单的HashMap
Map
这样的东西,以便使密钥尽可能简单String
很好地实现了hashCode
-方法。无论如何,我想您可以尝试使用TaskScheduler
来代替@Scheduled
-注释。您应该能够将CacheManager
-bean注入RunnableTask
,该任务调用其clear
-方法。@Thomas Kåsene,感谢您的建议。我将尝试将此TaskScheduler
与CacheManager
一起使用。感谢您的建议,但我只需要使用Spring internal的一些依赖项<根据约束条件,代码>com.github.ben-manes.2.8.2是不可接受的。请检查这是否解决了您的问题-
@Cacheable(cacheNames = "jwtTokenCache", value = "jwtToken", key = "#userId", condition = "#userId != null")