15. Using Scopes

对状态机中的作用域的支持非常有限,但可以使用普通的Spring @Scope注释来启用会话作用域。 首先,如果状态机是通过构建器手动构建的,并以@Bean的形式返回上下文,然后通过配置适配器返回。 这两种方法都需要一个@Scope来存在,其中scopeName设置为session,proxyMode设置为ScopedProxyMode.TARGET_CLASS。 下面显示了这两种用例的示例。

请参阅示例第45章,范围如何使用会话范围。

@Configuration
public class Config3 {

    @Bean
    @Scope(scopeName="session", proxyMode=ScopedProxyMode.TARGET_CLASS)
    StateMachine<String, String> stateMachine() throws Exception {
        Builder<String, String> builder = StateMachineBuilder.builder();
        builder.configureConfiguration()
            .withConfiguration()
                .autoStartup(true)
                .taskExecutor(new SyncTaskExecutor());
        builder.configureStates()
            .withStates()
                .initial("S1")
                .state("S2");
        builder.configureTransitions()
            .withExternal()
                .source("S1")
                .target("S2")
                .event("E1");
        StateMachine<String, String> stateMachine = builder.build();
        return stateMachine;
    }

}
@Configuration
@EnableStateMachine
@Scope(scopeName="session", proxyMode=ScopedProxyMode.TARGET_CLASS)
public static class Config4 extends StateMachineConfigurerAdapter<String, String> {

    @Override
    public void configure(StateMachineConfigurationConfigurer<String, String> config) throws Exception {
        config
            .withConfiguration()
                .autoStartup(true);
    }

    @Override
    public void configure(StateMachineStateConfigurer<String, String> states) throws Exception {
        states
            .withStates()
                .initial("S1")
                .state("S2");
    }

    @Override
    public void configure(StateMachineTransitionConfigurer<String, String> transitions) throws Exception {
        transitions
            .withExternal()
                .source("S1")
                .target("S2")
                .event("E1");
    }

}

一旦你将状态机限定在会话中,自动装配到一个@Controller将为每个会话提供新的状态机实例。 当HttpSession失效时,状态机将被销毁。

@Controller
public class StateMachineController {

    @Autowired
    StateMachine<String, String> stateMachine;

    @RequestMapping(path="/state", method=RequestMethod.POST)
    public HttpEntity<Void> setState(@RequestParam("event") String event) {
        stateMachine.sendEvent(event);
        return new ResponseEntity<Void>(HttpStatus.ACCEPTED);
    }

    @RequestMapping(path="/state", method=RequestMethod.GET)
    @ResponseBody
    public String getState() {
        return stateMachine.getState().getId();
    }
}

在会话范围中使用状态机需要仔细规划,主要是因为它是一个相对较重的组件

Spring Statemachine poms对Spring MVC类没有任何依赖关系,您将需要使用会话范围。 但是,如果您正在使用Web应用程序,那么您已经直接从Spring MVC或Spring Boot中取得了这些代码。

results matching ""

    No results matching ""