我有一个用例,其中单个条目需要在特定时间从缓存中删除。需要在键上而不是缓存级别上设置TTL。
在此春红文献之后,我尝试实现关键的特定TTL,但它不起作用。没有事件发生,我使用一个侦听器来检查它,当缓存ttl运行完时,只有一个事件发生。
缓存对象有一个带有来自@TimeToLive的org.springframework.data.redis.core.TimeToLive注释的字段,查看文档,这应该会在时间用完后触发一个过期事件。
缓存对象
@Data
@NoArgsConstructor
@AllArgsConstructor
public class BrandResponse {
@TimeToLive
private Long ttl;
@NotBlank
private String id;
}使用依赖项
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>2.6.6</version>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.6.3</version>
</dependency>启用关键空间事件
@SpringBootApplication
@ServletComponentScan
@EnableAsync
@EnableRedisRepositories(enableKeyspaceEvents = RedisKeyValueAdapter.EnableKeyspaceEvents.ON_STARTUP)
public class KikaRestApiApplication {
public static void main(String[] args) {
SpringApplication.run(KikaRestApiApplication.class, args);
}
}缓存的默认TTL为5分钟.entryTtl(Duration.ofMinutes(5))。
缓存设置
@Configuration
@EnableCaching
public class RedisCachingConfiguration {
private final KikaApiProperties kikaApiProperties;
@Value("${spring.redis.host}")
private String host;
@Value("${spring.redis.port}")
private Integer port;
public RedisCachingConfiguration(KikaApiProperties kikaApiProperties) {
this.kikaApiProperties = kikaApiProperties;
}
@Bean
public RedisCacheConfiguration cacheConfiguration() {
return RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofMinutes(5))
.disableCachingNullValues()
.serializeValuesWith(
SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));
}
@Bean
public RedisConnectionFactory redisConnectionFactory() {
RedisStandaloneConfiguration configuration = new RedisStandaloneConfiguration();
configuration.setHostName(host);
configuration.setPort(port);
return new JedisConnectionFactory(configuration);
}
@Bean
public RedisTemplate<String, Idmap> redisTemplate() {
RedisTemplate<String, Idmap> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory());
redisTemplate.setEnableTransactionSupport(true);
return redisTemplate;
}
}是否有什么东西是我缺少的做@TimeToLive与spring-redis缓存不一起工作。
发布于 2022-08-16 17:12:45
根据文件
TimeToLive在聚合根上标记一个数字属性,用于设置Redis中的过期值。带注释的属性取代任何其他超时配置。 RedisHash将对象标记为要存储在Redis散列中的聚合根。
默认的ttl单位是第二。@TimeToLive(unit = TimeUnit.SECONDS)您可以使用其他值,比如分钟。
在BrandResponse上使用@RedisHash。
下面是我的工作代码
@RedisHash
@Data
@NoArgsConstructor
@AllArgsConstructor
public class BrandResponse {
@TimeToLive(unit = TimeUnit.SECONDS )
private Long ttl;
@NotNull
@Id
private String id;
}
@Repository
public interface BrandRepository extends JpaRepository<BrandResponse, String> {
}
public interface CacheService {
void add(BrandResponse response);
boolean exists(String id);
}
@Service
public class RedisCacheServiceImpl implements CacheService {
@Autowired
private BrandRepository brandRepository;
@Override
public void add(BrandResponse response){
this.brandRepository.save(response);
}
@Override
public boolean exists(String id){
return !this.brandRepository.findById(id).isEmpty();
}
}
@Configuration
@EnableCaching
public class RedisCachingConfiguration {
private String host ="192.168.1.59";
private Integer port = 6379;
@Bean
public RedisCacheConfiguration cacheConfiguration() {
return RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofMinutes(5))
.disableCachingNullValues()
.serializeValuesWith(
RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));
}
@Bean
JedisConnectionFactory jedisConnectionFactory() {
JedisConnectionFactory jedisConFactory
= new JedisConnectionFactory();
jedisConFactory.setHostName(host);
jedisConFactory.setPort(port);
return jedisConFactory;
}
@Bean
public RedisTemplate<String, Object> redisTemplate() {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(jedisConnectionFactory());
return template;
}
}我使用了两个数据源,一个用于Redis,另一个用于db。
@SpringBootApplication
@EnableRedisRepositories(enableKeyspaceEvents = RedisKeyValueAdapter.EnableKeyspaceEvents.ON_STARTUP,
basePackages = {"com.c4c.authn.core.repository.redis"})
@EnableJpaRepositories(basePackages = {"com.c4c.authn.core.repository.db"})
public class AuthApplication {
public static void main(String[] args) {
SpringApplication.run(AuthApplication.class, args);
}
}单元测试
public class RedisCacheServiceImplTest extends BaseServiceTest {
@Autowired
private CacheService cacheService;
@Test
public void test_add_ok() throws InterruptedException {
this.cacheService.add(new BrandResponse(5l, "ID1"));
assertTrue(this.cacheService.exists("ID1"));
Thread.sleep(6000);
assertFalse(this.cacheService.exists("ID1"));
}
}https://stackoverflow.com/questions/73275520
复制相似问题