您不能通过使用普通的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"