spring statemachine持久化
您不能通过使用普通的java序列化来持久化,因为对象图太丰富,并且包含太多对其他Spring上下文类的依赖关系。 是状态机的运行时表示形式,可用于将现有计算机还原到由特定对象表示的状态。
spring官方表示不用直接用序列化方法来实现状态机的持久化。之前我是将statemachine存入一个hashmap中,但只能存在内存当中,docker容器重新部署之后,之前的数据就丢失了。为此,通过spring提供的持久化方法存入到redis当中。持久化内容StateMachineContext
非StateMachine
,只是持久化当前状态快照,恢复状态,不要求同一状态机。
StateMachineContext
是状态机的运行时表示形式(存储状态机当前状态的快照,可以从中获取StateMachine
),可用StateMachineContext
对象将状态机还原到特定的状态 。
-
首先,生成一个StateMachinePersist,这里是通过RedisConnectionFactory生成RepositoryStateMachinePersist,然后再包装输出StateMachinePersister,这里是RedisStateMachinePersister。
@Configuration public class PersistConfig { @Autowired private RedisConnectionFactory redisConnectionFactory; /** * 注入RedisStateMachinePersister对象 * * @return */ @Bean(name = "RedisPersister") public RedisStateMachinePersister<SessionStatus, SessionEvent> redisPersister() { return new RedisStateMachinePersister<>(redisPersist()); } /** * 通过redisConnectionFactory创建StateMachinePersist * * @return */ public StateMachinePersist<SessionStatus, SessionEvent, String> redisPersist() { RedisStateMachineContextRepository<SessionStatus, SessionEvent> repository = new RedisStateMachineContextRepository<>(redisConnectionFactory); return new RepositoryStateMachinePersist<>(repository); } }
-
然后在controller调用
StateMachine<SessionStatus,SessionEvent> stateMachine = new ApiStateMachineBuilder().build(beanFactory); stateMachinePersister.restore(stateMachine,sessionEntity1.getSessionId()); //restore是取 stateMachinePersister.persist(stateMachine,sessionEntity1.getSessionId()); //persist是存
-
在application.properties配置
#Redis服务器地址 #spring.redis.host=localhost spring.redis.host=172.22.0.1 #Redis服务器连接端口 spring.redis.port=6379 #Redis数据库索引(默认为0) spring.redis.database= 0 #连接超时时间(毫秒) spring.redis.timeout=1800000 #连接池最大连接数(使用负值表示没有限制) spring.redis.lettuce.pool.max-active=20 #最大阻塞等待时间(负数表示没限制) spring.redis.lettuce.pool.max-wait=-1 #连接池中的最大空闲连接 spring.redis.lettuce.pool.max-idle=5 #连接池中的最小空闲连接 spring.redis.lettuce.pool.min-idle=0
-
部署在docker中之后,修改redis的conf文件
-
ifconfig获取ip
@iZ8vb8s8t9gio6wq3bjc3bZ:/etc/redis$ ifconfig br-0a5afabfd675: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500 inet 172.22.0.1 netmask 255.255.0.0 broadcast 172.22.255.255 inet6 fe80::42:a9ff:fe3a:ef1a prefixlen 64 scopeid 0x20<link> ether 02:42:a9:3a:ef:1a txqueuelen 0 (Ethernet) RX packets 43 bytes 2596 (2.5 KB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 47 bytes 3566 (3.5 KB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
-
bind 127.0.0.1 -::1 修改为 bind 172.22.0.1 -::1
-
protected-mode 设置为no
-
终端输入:
redis-server
-
终端输入:
redis-cli -h 172.22.0.1 -p 6379
-
在redis中查询:
172.22.0.1:6379> keys * 1) "001" 172.22.0.1:6379> get 001 "\xac\xed\x00\x05ur\x00\x02[B\xac\xf3\x17\xf8\x06\bT\xe0\x02\x00\x00xp\x00\x00\x00\x9d\x01\x00\x01\x00com.haifeng.spring_boot_demo.bean.SessionStatu\xf3\x01\x11\x00\x01\x01org.springframework.statemachine.support.ObservableMa\xf0\x01\x00\x01\x02java.util.ArrayLis\xf4\x01\x00\x01\x03java.util.HashMa\xf0\x01\x00\x00"
-