如何在到期事件中访问 spring 数据 redis 存储对象? [英] How to acess spring data redis stored object at the expiration event?

查看:35
本文介绍了如何在到期事件中访问 spring 数据 redis 存储对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am storing a Cart in Redis using Spring Data Redis for a specific time. An expiration property annotated with @TimeToLive sets the time to live for the Cart object as described by the code below. I have set KeyExpirationEventMessageListener type to listen to the expiration event in order to process additional work at the expiration event. I was able to fetch the key from the triggered event of the expiration object and I am trying to access it or its phantom object at the expiry time using the spring data repository but with no result.It returns an empty object which means that the original obeject is likely been deleted. I don't know if it is the proper way to do it.But, is there a way to fetch the expiry object at expiration or just before it gets deleted to process motre work?

@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());
        }
    }

推荐答案

Example using Spring boot 2.3.4.RELEASE

Example using Spring boot 2.3.4.RELEASE

@RedisHash("cart")
@AllArgsConstructor
@Getter
@Setter
public class Cart implements Serializable {
    @Id
    @Indexed
    private String id;
    private String customerName;
    @TimeToLive
    private long expiration;
}

public interface ShoppingCartRepository extends CrudRepository<Cart, String> {
}

@SpringBootApplication
@EnableRedisRepositories(enableKeyspaceEvents = RedisKeyValueAdapter.EnableKeyspaceEvents.ON_STARTUP)
public class RedisExpirationApplication {

    public static void main(String[] args) {
        SpringApplication.run(RedisExpirationApplication.class, args);
    }

    @Bean
    public CommandLineRunner run(ShoppingCartRepository shoppingCartRepository) {
        return args -> {
            // TTL 1 second
            shoppingCartRepository.save(new Cart("some-id", "My Customer Name", 1));
            // wait 5 seconds
            Thread.sleep(5000L);
        };
    }

    @Component
    public class CartListener {
        // need to enable redis notifications, inside redis-cli type:
        // config set notify-keyspace-events KEA
        @EventListener
        public void anything(RedisKeyExpiredEvent<Cart> expiredCart) {
            Cart cart = (Cart) expiredCart.getValue();
            System.out.println(cart.getId());
            System.out.println(cart.getCustomerName());
        }
    }
}

这篇关于如何在到期事件中访问 spring 数据 redis 存储对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆