Правильный способ введения репозитория или службы в действие и защиту Spring statemachine

#java #spring #spring-statemachine

#java #spring #spring-statemachine

Вопрос:

Я вхожу в Spring Statemachine и моделирую с его помощью состояние заказа. Я прочитал об Guards и Actions , и, исходя из наших требований, возник вопрос.

Каков правильный способ введения Пружины @Repository или @Service в Guard или Action ?

Как описано в документации, Guard s и Action s настраиваются путем объявления a @Bean , но я не вижу способа ввести a @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 ?

Я был бы признателен за некоторое представление об этом, потому что я не смог найти ответа в документах.

Ответ №1:

Вы можете вводить зависимости на уровне метода:

 @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();
    };
}