使用新的Spring Statemachine项目,我可以在不使用适用于JavaConfig和Spring @Configuration类的适配器类的情况下以编程方式创建状态机吗?
我一直在研究Spring State Machine和State设计模式,因为我必须开发一个带有Spring Boot的微服务,并且需要清除许多混乱状态的持久对象,我正在寻找一个干净的设计解决方案.一塌糊涂.我检查了DDD,状态概念和状态机,看看要应用哪些
我不确定如何实现一些概念,以及如何连接它们.我想了解是否:
@Scope("prototype")我得到了: - DDD想要具有更多功能的域对象,这些功能简单,数据对象就像这个相当完整,但有关DDD的一篇有点过时的文章 - 状态模式应该封装Context元素在特定情况下应该如何表现 - 状态机是关于将一个国家与另一个国家之间的通道管理封装起来 - 如果它们一起工作,国家不应该指定哪个是特定指令的下一个国家,而是为国家机器和国家机器选择产生一个事件(或阻止是否有些卫兵失败了)新的国家 - 不知何故,新的国家必须由国家机器在上下文中设定
通常,Context对象应该直接委托给State对象.但是由于状态机决定了对象状态的变化,在这种情况下,Context是否应该委托给某种代理状态?应该将/ State机器注入实体还是代理?
任何想法,建议,甚至对其中一些问题的部分答案都将非常感激.
顺便说一句我
我使用Spring状态机和一些基本的Spring MVC应用程序.我必须承认,配置和使用非常简单.
但它也有许多局限性,主要是因为它处于发展的早期阶段.
我还遇到了一些像Activiti这样的工作流引擎,它是一个用Java编写的开源工作流引擎和一个轻量级Java状态机stateless4j.它们看起来更加精致和精致.
我想知道这些和Spring State Machine之间有什么区别(优点或缺点).
当我收到关于我的 API 的请求时,我想执行一系列步骤,每个步骤都是检查或充实。每一步都可能成功,也可能失败。成功后,应执行下一步。失败时,应执行结束步骤,并完成流程。为此,我考虑了 Spring 状态机,因为它似乎符合要求。
我已经阅读了文档并使用了它,但有些事情让我望而却步:
请求和状态机之间是否应该存在一对一的关系,这意味着对于每个请求,我都会创建一个新的状态机实例?或者我应该通过为下一个请求重置机器来以某种方式重用已完成的状态机?
完成状态机的清理怎么样?似乎没有办法销毁和清理状态机实例。如果我为每个请求创建 1 个,我实际上已经引入了内存泄漏,除非框架以某种方式处理资源。
我有一个带有 n 个消息侦听器的事件队列。当消息到达时,一个消息侦听器接收它并执行状态机的一个新实例。我面临的问题是,虽然多条消息是并行处理的,但状态机开始按顺序执行动作,尽管它们是由不同的状态机实例调用的,如下所示:
2017-10-18 16:11:03.740 INFO 30282 --- [lTaskExecutor-1] o.s.s.support.LifecycleObjectSupport : started org.springframework.statemachine.support.DefaultStateMachineExecutor@6ddb1ea6
2017-10-18 16:11:03.741 INFO 30282 --- [lTaskExecutor-1] o.s.s.support.LifecycleObjectSupport : started EVALUATE_IS_WALKTHROUGH SAVE END START / START / uuid=b922b6b1-a441-4924-8531-d45e0e0c9c40 / id=null
2017-10-18 16:11:03.740 INFO 30282 --- [TaskExecutor-10] o.s.s.support.LifecycleObjectSupport : started org.springframework.statemachine.support.DefaultStateMachineExecutor@13b6ace4
2017-10-18 16:11:03.741 INFO 30282 --- [TaskExecutor-10] o.s.s.support.LifecycleObjectSupport : started EVALUATE_IS_WALKTHROUGH SAVE END START / START / uuid=e06a8c1d-beed-41c6-bc63-d8c1a3a56169 / id=null
2017-10-18 16:11:03.759 INFO 30282 --- [pool-5-thread-1] i.b.b.e.processors.actions.SaveAction : [io.botbit.backend.events.processors.actions.SaveAction@607e4071] Saving event Event[id=null,
2017-10-18 16:11:24.046 INFO 30282 --- [pool-5-thread-1] i.b.b.e.processors.actions.SaveAction …Run Code Online (Sandbox Code Playgroud) 我们正在考虑将Spring State Machine用于以下用例:
我们的一个实体(即我们的域模型中的JPA实体)可以位于多个州之一,我们有数百万个这样的实体(以及我们数据库中的许多行).
我们正在考虑使用:
org.springframework.statemachine.data.jpa.JpaStateRepository
Run Code Online (Sandbox Code Playgroud)
我们应该使用域模型类注释JpaRepositoryState,从而在我们的域模型和弹簧状态机之间创建依赖关系吗?
什么是上面的替代,即确保我们的JPA实体类没有太紧密耦合JpaRepositoryState?
状态机machineId和JPA实体之间的映射/关系是@Id什么?
我目前正在使用 Spring 状态机构建一个小示例项目。
我的配置:
@Configuration
@EnableStateMachine
public class StateMachineConfiguration extends EnumStateMachineConfigurerAdapter<States, Events> {
@Override
public void configure(StateMachineStateConfigurer<States, Events> states)
throws Exception {
states
.withStates()
.initial(States.LOCKED)
.states(EnumSet.allOf(States.class));
}
@Override
public void configure(StateMachineTransitionConfigurer<States, Events> transitions)
throws Exception {
transitions
.withExternal()
.source(States.LOCKED)
.target(States.UNLOCKED)
.event(Events.COIN)
.and()
.withExternal()
.source(States.UNLOCKED)
.target(States.LOCKED)
.event(Events.PUSH);
}
@Bean
public StateMachineListener<States, Events> listener() {
return new StateMachineListenerAdapter<States, Events>() {
@Override
public void stateChanged(State<States, Events> from, State<States, Events> to) {
System.out.println("State change to " + to.getId());
}
};
}
}
Run Code Online (Sandbox Code Playgroud)
当我现在尝试注入状态机时
@Autowired …Run Code Online (Sandbox Code Playgroud) 我有这个简单的状态机配置:
@Configuration
@EnableStateMachine
public class SimpleStateMachineConfiguration extends StateMachineConfigurerAdapter<State, Boolean> {
@Override
public void configure(StateMachineStateConfigurer<State, Boolean> states) throws Exception {
states.withStates()
.initial(State.INITIAL)
.states(EnumSet.allOf(State.class));
}
@Override
public void configure(StateMachineTransitionConfigurer<State, Boolean> transitions) throws Exception {
transitions
.withExternal()
.source(State.INITIAL)
.target(State.HAS_CUSTOMER_NUMBER)
.event(true)
.action(retrieveCustomerAction())
// here I'd like to retrieve the customer from this action, like:
// stateMachine.start();
// stateMachine.sendEvent(true);
// stateMachine.retrieveCustomerFromAction();
.and()
.withExternal()
.source(State.INITIAL)
.target(State.NO_CUSTOMER_NUMBER)
.event(false)
.action(createCustomerAction());
// here I'd like to send the customer instance to create, like:
// stateMachine.start();
// stateMachine.sendEvent(false);
// stateMachine.sendCustomerToAction(Customer …Run Code Online (Sandbox Code Playgroud) 我有一个用例,其中事务经历以下多个状态
弹簧状态机是这种流程的正确解决方案吗,还是弹簧可流动更合适。
何时使用 Spring State Machine 或 Spring Flowable 的基本检查是什么。
我试图弄清楚如何轻松使用 Spring 状态机,包括使用 JPA 进行持久化。这是我正在处理的问题:
不兼容的数据类型 - 工厂和持久性
在程序的某个时刻,我想使用连接到用户的状态机。有用于此目的的存储库(项目spring-statemachine-data-jpa)。首先,使用存储库检查玩家的状态机是否已存在。如果没有,则创建一个新的状态机并保留它。
问题是我有不同类型的状态机。工厂创建一个StateMachine<UserState, UserEvent>,存储库返回一个JpaRepositoryStateMachine。这些彼此不兼容,对我来说,不清楚如何持久/创建/恢复状态机。
你能为我澄清一下吗?
@Autowired
private StateMachineRepository<JpaRepositoryStateMachine> repository;
public someMethod(User user) {
Optional<JpaRepositoryStateMachine> stateMachine = repository.findById(user.getId()); // JPA state machine
if(stateMachine.isEmpty()) {
StateMachine<UserState, UserEvent> createdStateMachine = factory.getStateMachine(user.getId()); // spring state machine
repository.save(createdStateMachine); // compile error
}
// here: ready-to-use statemachine - how?
}
Run Code Online (Sandbox Code Playgroud)
感谢您的帮助!