我已经进入了Spring Statemachine,并用它对订单的状态进行建模。我读到了关于Guards
和Actions
的文章,根据我们的需求,出现了一个问题。
将Spring@Repository
或@Service
注入Guard
或Action
的正确方法是什么?
如文档中所述,Guard
s和Action
s是通过声明@Bean
来配置的,但我看不到以这种方式注入@Service
或@Repository
的方法。
例如,以这个EnumStateMachineConfigurerAdapter
为例:
@Configuration
@EnableStateMachineFactory
public class OrderStateMachineConfiguration extends EnumStateMachineConfigurerAdapter<OrderStates, OrderEvents> {
@Override
public void configure(StateMachineStateConfigurer<OrderStates, OrderEvents> states) throws Exception {
states
.withStates()
.initial(OrderStates.PENDING)
.initial(OrderStates.APPROVED)
.initial(OrderStates.PAYMENT_REJECTED)
.end(OrderStates.DELIVERED)
.end(OrderStates.CANCELLED)
.end(OrderStates.INVALID)
.end(OrderStates.REFUNDED)
.end(OrderStates.ARCHIVED)
.states(EnumSet.allOf(OrderStates.class));
}
@Override
public void configure(StateMachineConfigurationConfigurer<OrderStates, OrderEvents> config) throws Exception {
config
.withConfiguration()
.listener(new StateMachineListener());
}
@Override
public void configure(StateMachineTransitionConfigurer<OrderStates, OrderEvents> transitions) throws Exception {
transitions
.withExternal().source(OrderStates.PENDING).target(OrderStates.APPROVED).event(OrderEvents.APPROVE).and()
... more transitions
}
@Bean
public Guard<OrderStates, OrderEvents> orderIsConsistent() {
return ctx -> {
Order order = ctx.getExtendedState().get(ORDER_KEY, Order.class);
return order.getInconsistencies().isEmpty();
};
}
}
将@Autowired
作为顶部的服务似乎是不对的,因为这是一个@Configuration
类,更不用说循环引用的风险了。
我提出的另一个解决方案可能是在创建状态机时将所需的服务注入extendedState
或状态机标头,然后通过StateContext
访问它?
我很感激能对此有所了解,因为我在文档中找不到答案。
您可以在方法级别注入依赖项:
@Bean
@Autowired
public Guard<OrderStates, OrderEvents> orderIsConsistent(OrderService orderService) {
return ctx -> {
Long orderId = ctx.getExtendedState().get(ORDER_ID, Long.class);
Order order = orderService.findById(orderId);
return order.getInconsistencies().isEmpty();
};
}