如何在到期事件中重新访问弹簧数据存储的对象?

问题描述 投票:0回答:1

我正在使用Spring Data Redis在特定时间将购物车存储在Redis中。用@TimeToLive注释的到期属性设置了Cart对象的生存时间,如下面的代码所述。我已将KeyExpirationEventMessageListener类型设置为侦听到期事件,以便在到期事件上处理其他工作。我能够从过期对象的触发事件中获取密钥,并且试图在过期时使用spring数据存储库访问它或其幻像对象,但没有结果,它返回一个空对象,这意味着原始对象对象可能已删除。我不知道这是否是正确的方法,但是,是否有一种方法可以在到期时或在删除删除对象以进行后续工作之前获取到期对象?

@RedisHash("cart")
public class Cart implements Serializable {
    @Id
    @Indexed
    private String id;
    private long customerId;
    private Set<CartLine> lines = new HashSet<>();

    @TimeToLive
    private long expiration;

}

public interface ShoppingCartRepository extends CrudRepository<Cart, String> {

}


    @Component
    public class RedisKeyExpirationListener extends KeyExpirationEventMessageListener {

        private RedisTemplate<?, ?> redisTemplate;
        private ShoppingCartRepository repository;
        public RedisKeyExpirationListener(RedisMessageListenerContainer listenerContainer,
                                          RedisTemplate redisTemplate, ShoppingCartRepository repository) {
            super(listenerContainer);
            this.redisTemplate = redisTemplate;
            this.repository = repository;
        }

        @Override
        public void onMessage(Message message, byte[] pattern) {
            String key = new String(message.getBody());
            try {
                String id = extractId(key);
                Optional<ShoppingCart> cart = repository.findById(id);
            } catch(Exception e) {
                logger.info("something went wrong  ====>  " + e.getStackTrace());
            }
        }
        private String extractId(String key){
            String keyPrefix = ShoppingCart.class.getAnnotation(RedisHash.class).value();
            return key.substring((keyPrefix + ":").length());
        }
    }

spring-boot spring-data spring-data-redis
1个回答
0
投票

在我的场景中曾经有一个用例,您实际上可以使用RedisKeyExpiredEvent,

  • RedisKeyExpiredEvent [0]是Redis特定的ApplicationEvent已发布Redis中的特定密钥过期时。它可以保留密钥旁边的过期密钥。

您可以继续以下实现。

@SpringBootApplication
@EnableRedisRepositories(considerNestedRepositories = true, enableKeyspaceEvents = EnableKeyspaceEvents.ON_STARTUP)
static class Config {

    /**
     * An {@link ApplicationListener} that captures {@link RedisKeyExpiredEvent}s and just prints the value to the
     * console.
     *
     * @return
     */
    @Bean
    ApplicationListener<RedisKeyExpiredEvent<Person>> eventListener() {
        return event -> {
            System.out.println(String.format("Received expire event for key=%s with value %s.",
                    new String(event.getSource()), event.getValue()));
        };
    }
}

您可以在[1]中找到示例实现。

© www.soinside.com 2019 - 2024. All rights reserved.