上一章对状态机Spring StateMachine做了基础介绍,这次重点说明一下Spring StateMachine缺点。然后针对这个做具体优化
目标:
1.提高代码复用率
2.修复一些bug
3.让使用姿势更加舒服(本人很懒,不想重复劳动^_^)
4.单据密等
5.单据加锁
1.缺点:
1. Spring StateMachine是一个“重量级”状态机框架,说他重是不框架本身比较庞大,而是说他的创建比较笨重,生产上我们一般都是用工厂模式来创建状态机,这样一来每一个请求都会创建一个StateMachine对象,这样一来在高并发场景下,会创建N个StateMachine对象,对内存压力就大了。(做过测试2分钟内60w个并发请求,内存消耗算太大几百兆而已)
2.StateMachine对spring事务不支持。(关键很致命)
3.stateMachine无法抛出异常,异常会被状态机给消化掉。
4.出生时间较短,文档和相关资料不是很全,且还存在一些bug。
(别问我为啥选它,问了也白问^_^)
针对上面问题,具体解决方案;
2.解决方案:
1.“重量级" 级问题
a.第一种方式:利用Threadlocal来储存stateMachine,这样可以达到stateNachine局部复用。(简单粗暴,注意手动释放Threadlocal,不然会出现内存溢出,意义不大)
b.自己定义一个对象池,将每次利用完成的stateMachine初始化后放回池里,每次取对象都从对象池中获取stateMachine。(相对复杂,处理不好容易出现并发性问题)
2.StateMachine对spring事务不支持
利用@Transactional 注解特性将这个注解加到类上,这样可以保证事务可以传递。
3. stateMachine无法抛出异常,异常会被状态机给消化掉
利用反射,重写源码就可以解决。
3.源代码解决:
这里不解决“重量级" 级问题,原因是如果真的有那么高的并发量,建议不要是用stateMachine,而去使用squirrel-foundation,这个更加轻量级而且没有上面的问题。
这里主要是针对stateMachine做二次包装,目的是为了提高代码复用率和方便开发
基础配置类:状态机工厂配置
/**
* 状态机工厂基础配置类
*/
@Configuration
@EnableStateMachineFactory(name = "OneStateMachineFactory")
public class OneStateMachineConfig extends StateMachineConfigurerAdapter<StateEnum, EventEnum> {
/**
* 状态机配置类
**/
@Resource
private OutBoundBuilderMachineConfig outBoundBuilderMachineConfig;
@Override
public void configure(StateMachineStateConfigurer<StateEnum, EventEnum> states)
throws Exception {
outBoundBuilderMachineConfig.configureState(states);
}
@Override
public void configure(StateMachineTransitionConfigurer<StateEnum, EventEnum> transitions)
throws Exception {
outBoundBuilderMachineConfig.configureStateBindEvent(transitions);
}
/**
* 扩展StateMachinePersist
*/
@Bean(name = "oneFactoryPersist")
public StateMachinePersister<StateEnum, EventEnum, EventObj<StateEnum, EventEnum>> factoryPersister(){
return new DefaultStateMachinePersister(new ExtStateMachinePersist<String, String, EventObj<String, String>>());
}
/**
* 扩展StateMachineFactory
*/
@Bean(name = "oneExtStateMachineFactory")
public ExtStateMachineFactory<StateEnum, EventEnum> extStateMachineFactory(@Autowired @Qualifier("OneStateMachineFactory") StateMachineFactory stateMachineFactory) {
return new ExtStateMachineFactory(stateMachineFactory);
}
/**
* 扩展StateMachineBuilder
*/
@Bean(name = "oneStateMachineBuilder")
public ExtStateMachineBuilder<StateEnum, EventEnum> extStateMachineBuilder(@Autowired @Qualifier("outBoundExtStateMachineFactory") ExtStateMachineFactory extStateMachineFactory) {
return new ExtStateMachineBuilder(extStateMachineFactory, factoryPersister());
}
}
状态配置类:业务逻辑状态机配置
/**
* 状态机配置类
**/
@Service
public class OutBoundBuilderMachineConfig {
/**
* 业务代码实现service
*/
@Resource
privateCreateAction createAction;
@Resource
private wareHouseAction wareHouseAction;
@Resource
private CancelAction cancelAction;
@Resource
private ShelfAction shelfAction;
@Resource
private StockAction stockAction;
/**
* 构建出库状态绑定关系
*
* @param states 状态机状态
*/
public void configureState(StateMachineStateConfigurer<StateEnum, EventEnum> states) throws Exception {
states.withStates()
.initial(OutBoundStateEnum.INIT)
.states(EnumSet.allOf(OutBoundStateEnum.class));
}
/**
* 构建状态机状态绑定事件关联关系
*
* @param transitions 参数
*/
public voi