Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/361.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 @可缓存和@计划在Spring引导应用程序中同时启动_Java_Spring Boot_Caching_Jwt_Scheduling - Fatal编程技术网

Java @可缓存和@计划在Spring引导应用程序中同时启动

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

前言:在一个产品(一组spring boot应用程序)中,我的工作是使用JWT令牌进行安全保护,从内部服务器获取,并使用它通过REST调用在服务之间进行通信

问题:JWT令牌TTL精确到2小时,因此我尝试将其放入缓存中,以便对于给定的
用户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.我第一次想到使用一个简单的HashMapObject{String:userId,OffsetDateTime:startTimestamp},V->String:jwtticket>,但是我的前辈让我在这里使用Spring中的一些东西。2.我同意这些性能问题。但这在这个应用程序中是允许的,产品是异步的,大部分通信都使用Kafka,其余的调用很少。我想更多的是像
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")