spring-state-machine使用redis持久化

本文涉及的产品
云原生内存数据库 Tair,内存型 2GB
云数据库 Redis 版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: spring-state-machine使用redis持久化

之前介绍过spring-state-machine持久化

今天使用redis实现

首先是需要一个RedisStateMachineRepository

import com.alibaba.nacos.common.utils.JacksonUtils;
import jakarta.annotation.Nonnull;
import jakarta.annotation.Resource;
import org.dromara.streamquery.stream.core.stream.Steam;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.statemachine.data.redis.RedisRepositoryStateMachine;
import org.springframework.statemachine.data.redis.RedisStateMachineRepository;
import org.springframework.stereotype.Repository;

import java.util.Optional;

@Repository
public class StateMachineRedisRepository implements RedisStateMachineRepository {


    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Nonnull
    @Override
    public <S extends RedisRepositoryStateMachine> S save(@Nonnull S entity) {
        stringRedisTemplate.opsForHash()
                .put(SmCacheConst.STATE_MACHINE, entity.getId(), serialize(entity));
        return entity;
    }

    @Nonnull
    @Override
    public <S extends RedisRepositoryStateMachine> Iterable<S> saveAll(@Nonnull Iterable<S> entities) {
        var map = Steam.of(entities).toMap(RedisRepositoryStateMachine::getId, this::serialize);
        stringRedisTemplate.opsForHash().putAll(SmCacheConst.STATE_MACHINE, map);
        return Steam.of(entities).toList();
    }

    @Nonnull
    @Override
    public Optional<RedisRepositoryStateMachine> findById(@Nonnull String s) {
        return Optional.ofNullable(stringRedisTemplate.opsForHash().get(SmCacheConst.STATE_MACHINE, s)).map(this::deserialize);
    }

    @Override
    public boolean existsById(@Nonnull String s) {
        return stringRedisTemplate.opsForHash().hasKey(SmCacheConst.STATE_MACHINE, s);
    }

    @Nonnull
    @Override
    public Iterable<RedisRepositoryStateMachine> findAll() {
        return Steam.of(stringRedisTemplate.opsForHash().values(SmCacheConst.STATE_MACHINE)).map(this::deserialize).toList();
    }

    @Nonnull
    @Override
    public Iterable<RedisRepositoryStateMachine> findAllById(@Nonnull Iterable<String> strings) {
        var ids = Steam.<Object>of(strings).toList();
        var list = stringRedisTemplate.opsForHash().multiGet(SmCacheConst.STATE_MACHINE, ids);
        return Steam.of(list).map(this::deserialize).toList();
    }


    @Override
    public long count() {
        return stringRedisTemplate.opsForHash().size(SmCacheConst.STATE_MACHINE);
    }

    @Override
    public void deleteById(@Nonnull String s) {
        stringRedisTemplate.opsForHash().delete(SmCacheConst.STATE_MACHINE, s);
    }

    @Override
    public void delete(@Nonnull RedisRepositoryStateMachine entity) {
        stringRedisTemplate.opsForHash().delete(SmCacheConst.STATE_MACHINE, entity.getId());
    }

    @Override
    public void deleteAllById(@Nonnull Iterable<? extends String> strings) {
        var array = Steam.of(strings).toArray();
        stringRedisTemplate.opsForHash().delete(SmCacheConst.STATE_MACHINE, array);
    }

    @Override
    public void deleteAll(@Nonnull Iterable<? extends RedisRepositoryStateMachine> entities) {
        var ids = Steam.of(entities).map(RedisRepositoryStateMachine::getId).toArray();
        stringRedisTemplate.opsForHash().delete(SmCacheConst.STATE_MACHINE, ids);
    }

    @Override
    public void deleteAll() {
        stringRedisTemplate.opsForHash().delete(SmCacheConst.STATE_MACHINE);
    }

    private String serialize(Object entity) {
        return JacksonUtils.toJson(entity);
    }

    private RedisRepositoryStateMachine deserialize(Object obj) {
        if (obj instanceof String json) {
            return JacksonUtils.toObj(json, RedisRepositoryStateMachine.class);
        }
        return null;
    }
}

然后是配置:

@Bean
public StateMachineRuntimePersister<WordChainStateEnum, WordChainEventEnum, String>
stateMachineRuntimePersister(StateMachineRedisRepository stateMachineRedisRepository) {
    return new RedisPersistingStateMachineInterceptor<>(stateMachineRedisRepository);
}

@Bean
public StateMachineService<WordChainStateEnum, WordChainEventEnum>
stateMachineService(StateMachineFactory<WordChainStateEnum, WordChainEventEnum> stateMachineFactory,
                    StateMachineRuntimePersister<WordChainStateEnum, WordChainEventEnum, String> stateMachineRuntimePersister) {
    return new DefaultStateMachineService<>(stateMachineFactory, stateMachineRuntimePersister);
}

接下来是状态机处使用

StateMachineBuilder.Builder<WordChainStateEnum, WordChainEventEnum> builder = StateMachineBuilder.builder();

builder.configureConfiguration().withConfiguration().machineId(room);

builder.configureStates().withStates()
       .initial(STATE_WAITING_FOR_READY)
       .states(Set.of(WordChainStateEnum.values()));

builder.configureConfiguration().withPersistence().runtimePersister(stateMachineRuntimePersister);
相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
6天前
|
缓存 NoSQL Java
【Azure Redis 缓存】示例使用 redisson-spring-boot-starter 连接/使用 Azure Redis 服务
【Azure Redis 缓存】示例使用 redisson-spring-boot-starter 连接/使用 Azure Redis 服务
|
12天前
|
NoSQL Java Redis
Redis6入门到实战------ 八、Redis与Spring Boot整合
这篇文章详细介绍了如何在Spring Boot项目中整合Redis,包括在`pom.xml`中添加依赖、配置`application.properties`文件、创建配置类以及编写测试类来验证Redis的连接和基本操作。
Redis6入门到实战------ 八、Redis与Spring Boot整合
|
1天前
|
编解码 NoSQL Java
使用Spring Boot + Redis 队列实现视频文件上传及FFmpeg转码的技术分享
【8月更文挑战第30天】在当前的互联网应用中,视频内容的处理与分发已成为不可或缺的一部分。对于视频平台而言,高效、稳定地处理用户上传的视频文件,并对其进行转码以适应不同设备的播放需求,是提升用户体验的关键。本文将围绕使用Spring Boot结合Redis队列技术来实现视频文件上传及FFmpeg转码的过程,分享一系列技术干货。
13 3
|
10天前
|
NoSQL Redis
Redis 临时manifest修改问题之确保被持久化到磁盘如何解决
Redis 临时manifest修改问题之确保被持久化到磁盘如何解决
|
2天前
|
缓存 NoSQL Java
惊!Spring Boot遇上Redis,竟开启了一场缓存实战的革命!
【8月更文挑战第29天】在互联网时代,数据的高速读写至关重要。Spring Boot凭借简洁高效的特点广受开发者喜爱,而Redis作为高性能内存数据库,在缓存和消息队列领域表现出色。本文通过电商平台商品推荐系统的实战案例,详细介绍如何在Spring Boot项目中整合Redis,提升系统响应速度和用户体验。
18 0
|
28天前
|
NoSQL Java Redis
Spring Boot集成Redis全攻略:高效数据存取,打造性能飞跃的Java微服务应用!
【8月更文挑战第3天】Spring Boot是备受欢迎的微服务框架,以其快速开发与轻量特性著称。结合高性能键值数据库Redis,可显著增强应用性能。集成步骤包括:添加`spring-boot-starter-data-redis`依赖,配置Redis服务器参数,注入`RedisTemplate`或`StringRedisTemplate`进行数据操作。这种集成方案适用于缓存、高并发等场景,有效提升数据处理效率。
129 2
|
7天前
|
缓存 NoSQL Java
【Azure Redis 缓存】定位Java Spring Boot 使用 Jedis 或 Lettuce 无法连接到 Redis的网络连通性步骤
【Azure Redis 缓存】定位Java Spring Boot 使用 Jedis 或 Lettuce 无法连接到 Redis的网络连通性步骤
|
30天前
|
NoSQL Java API
Spring Boot 中集成Redis
主要介绍了 redis 的使用场景、安装过程,以及 Spring Boot 中集成 redis 的详细步骤。在实际项目中,通常都用 redis 作为缓存,在查询数据库的时候,会先从 redis 中查找,如果有信息,则从 redis 中取;如果没有,则从数据库中查,并且同步到 redis 中,下次 redis 中就有了。更新和删除也是如此,都需要同步到 redis。redis 在高并发场景下运用的很多。
|
18天前
|
NoSQL 安全 Java
Java Spring Boot中使用Shiro、JWT和Redis实现用户登录鉴权
Java Spring Boot中使用Shiro、JWT和Redis实现用户登录鉴权
|
22天前
|
缓存 NoSQL Java
Spring基于注解整合Redis
【8月更文挑战第5天】
下一篇
云函数