diff --git a/spring-statemachine-core/src/main/java/org/springframework/statemachine/config/AbstractStateMachineFactory.java b/spring-statemachine-core/src/main/java/org/springframework/statemachine/config/AbstractStateMachineFactory.java index 77478dcf..baf4354c 100644 --- a/spring-statemachine-core/src/main/java/org/springframework/statemachine/config/AbstractStateMachineFactory.java +++ b/spring-statemachine-core/src/main/java/org/springframework/statemachine/config/AbstractStateMachineFactory.java @@ -69,7 +69,7 @@ import org.springframework.statemachine.trigger.Trigger; import org.springframework.util.ObjectUtils; /** - * {@link StateMachineFactory} implementation using enums to build {@link StateMachine}s. + * Base {@link StateMachineFactory} implementation building {@link StateMachine}s. * * @author Janne Valkealahti * @@ -226,10 +226,21 @@ public abstract class AbstractStateMachineFactory extends LifecycleObjectS return delegateAutoStartup(machine); } + /** + * Instructs this factory to handle auto-start flag manually + * by calling lifecycle start method. + * + * @param handleAutostartup the new handle autostartup + */ public void setHandleAutostartup(boolean handleAutostartup) { this.handleAutostartup = handleAutostartup; } + /** + * Instructs this factory to enable application context events. + * + * @param contextEvents the new context events enabled + */ public void setContextEventsEnabled(Boolean contextEvents) { this.contextEvents = contextEvents; } diff --git a/spring-statemachine-core/src/main/java/org/springframework/statemachine/config/EnableStateMachine.java b/spring-statemachine-core/src/main/java/org/springframework/statemachine/config/EnableStateMachine.java index 7afb0d62..b5d1774c 100644 --- a/spring-statemachine-core/src/main/java/org/springframework/statemachine/config/EnableStateMachine.java +++ b/spring-statemachine-core/src/main/java/org/springframework/statemachine/config/EnableStateMachine.java @@ -33,7 +33,8 @@ import org.springframework.statemachine.config.configuration.StateMachineConfigu import org.springframework.statemachine.config.configuration.StateMachineConfigurationImportSelector; /** - * Example annotation which imports @{@link Configuration}s. + * Annotation which imports @{@link Configuration}s related to + * building state machines. * * @author Janne Valkealahti * diff --git a/spring-statemachine-core/src/main/java/org/springframework/statemachine/config/EnableStateMachineFactory.java b/spring-statemachine-core/src/main/java/org/springframework/statemachine/config/EnableStateMachineFactory.java index 4daad950..9b628cbb 100644 --- a/spring-statemachine-core/src/main/java/org/springframework/statemachine/config/EnableStateMachineFactory.java +++ b/spring-statemachine-core/src/main/java/org/springframework/statemachine/config/EnableStateMachineFactory.java @@ -33,7 +33,8 @@ import org.springframework.statemachine.config.configuration.StateMachineConfigu import org.springframework.statemachine.config.configuration.StateMachineFactoryConfiguration; /** - * Example annotation which imports @{@link Configuration}s. + * Annotation which imports @{@link Configuration}s related to + * building state machine factories. * * @author Janne Valkealahti * diff --git a/spring-statemachine-core/src/main/java/org/springframework/statemachine/config/configuration/StateMachineFactoryConfiguration.java b/spring-statemachine-core/src/main/java/org/springframework/statemachine/config/configuration/StateMachineFactoryConfiguration.java index 36853d86..0b3b6a42 100644 --- a/spring-statemachine-core/src/main/java/org/springframework/statemachine/config/configuration/StateMachineFactoryConfiguration.java +++ b/spring-statemachine-core/src/main/java/org/springframework/statemachine/config/configuration/StateMachineFactoryConfiguration.java @@ -110,11 +110,17 @@ public class StateMachineFactoryConfiguration, E extends Enum< StateMachineConfig stateMachineConfig = builder.getOrBuild(); StateMachineTransitions stateMachineTransitions = stateMachineConfig.getTransitions(); StateMachineStates stateMachineStates = stateMachineConfig.getStates(); - StateMachineConfigurationConfig stateMachineConfigurationConfig = stateMachineConfig.getStateMachineConfigurationConfig(); - ObjectStateMachineFactory enumStateMachineFactory = new ObjectStateMachineFactory(stateMachineConfigurationConfig, stateMachineTransitions, stateMachineStates); - enumStateMachineFactory.setBeanFactory(beanFactory); - enumStateMachineFactory.setContextEventsEnabled(contextEvents); - this.stateMachineFactory = enumStateMachineFactory; + StateMachineConfigurationConfig stateMachineConfigurationConfig = stateMachineConfig + .getStateMachineConfigurationConfig(); + ObjectStateMachineFactory objectStateMachineFactory = new ObjectStateMachineFactory( + stateMachineConfigurationConfig, stateMachineTransitions, stateMachineStates); + objectStateMachineFactory.setBeanFactory(beanFactory); + objectStateMachineFactory.setContextEventsEnabled(contextEvents); + // explicitly tell factory to handle auto-start because + // machine is not created as a bean so factory need to + // call lifecycle methods manually + objectStateMachineFactory.setHandleAutostartup(true); + this.stateMachineFactory = objectStateMachineFactory; } @Override diff --git a/spring-statemachine-core/src/test/java/org/springframework/statemachine/StateMachineFactoryTests.java b/spring-statemachine-core/src/test/java/org/springframework/statemachine/StateMachineFactoryTests.java index ba717a00..19cc3bcc 100644 --- a/spring-statemachine-core/src/test/java/org/springframework/statemachine/StateMachineFactoryTests.java +++ b/spring-statemachine-core/src/test/java/org/springframework/statemachine/StateMachineFactoryTests.java @@ -16,9 +16,13 @@ package org.springframework.statemachine; import static org.hamcrest.Matchers.contains; +import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertThat; +import java.util.EnumSet; + import org.junit.Test; +import org.springframework.context.SmartLifecycle; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -28,30 +32,63 @@ import org.springframework.messaging.support.MessageBuilder; import org.springframework.statemachine.config.EnableStateMachineFactory; import org.springframework.statemachine.config.EnumStateMachineConfigurerAdapter; import org.springframework.statemachine.config.ObjectStateMachineFactory; +import org.springframework.statemachine.config.StateMachineFactory; +import org.springframework.statemachine.config.builders.StateMachineConfigurationConfigurer; import org.springframework.statemachine.config.builders.StateMachineStateConfigurer; import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer; public class StateMachineFactoryTests extends AbstractStateMachineTests { + @Override + protected AnnotationConfigApplicationContext buildContext() { + return new AnnotationConfigApplicationContext(); + } + @SuppressWarnings({ "unchecked" }) @Test public void testMachineFromFactory() { - AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(Config.class); + context.register(Config1.class); + context.refresh(); ObjectStateMachineFactory stateMachineFactory = - ctx.getBean(StateMachineSystemConstants.DEFAULT_ID_STATEMACHINEFACTORY, ObjectStateMachineFactory.class); + context.getBean(StateMachineSystemConstants.DEFAULT_ID_STATEMACHINEFACTORY, ObjectStateMachineFactory.class); StateMachine machine = stateMachineFactory.getStateMachine(); machine.start(); assertThat(machine.getState().getIds(), contains(TestStates.S1)); machine.sendEvent(MessageBuilder.withPayload(TestEvents.E1).build()); assertThat(machine.getState().getIds(), contains(TestStates.S2)); - ctx.close(); + } + + @SuppressWarnings({ "unchecked" }) + @Test + public void testAutoStartFlagOn() throws Exception { + context.register(Config2.class); + context.refresh(); + StateMachineFactory stateMachineFactory = + context.getBean(StateMachineSystemConstants.DEFAULT_ID_STATEMACHINEFACTORY, StateMachineFactory.class); + StateMachine machine = stateMachineFactory.getStateMachine(); + + assertThat(((SmartLifecycle)machine).isAutoStartup(), is(true)); + assertThat(((SmartLifecycle)machine).isRunning(), is(true)); + } + + @SuppressWarnings({ "unchecked" }) + @Test + public void testAutoStartFlagOff() throws Exception { + context.register(Config3.class); + context.refresh(); + StateMachineFactory stateMachineFactory = + context.getBean(StateMachineSystemConstants.DEFAULT_ID_STATEMACHINEFACTORY, StateMachineFactory.class); + StateMachine machine = stateMachineFactory.getStateMachine(); + + assertThat(((SmartLifecycle)machine).isAutoStartup(), is(false)); + assertThat(((SmartLifecycle)machine).isRunning(), is(false)); } @Configuration @EnableStateMachineFactory - static class Config extends EnumStateMachineConfigurerAdapter { + static class Config1 extends EnumStateMachineConfigurerAdapter { @Override public void configure(StateMachineStateConfigurer states) throws Exception { @@ -78,4 +115,46 @@ public class StateMachineFactoryTests extends AbstractStateMachineTests { } + @Configuration + @EnableStateMachineFactory + public static class Config2 extends EnumStateMachineConfigurerAdapter { + + @Override + public void configure(StateMachineConfigurationConfigurer config) throws Exception { + config + .withConfiguration() + .autoStartup(true); + } + + @Override + public void configure(StateMachineStateConfigurer states) throws Exception { + states + .withStates() + .initial(TestStates.S1) + .states(EnumSet.allOf(TestStates.class)); + } + + } + + @Configuration + @EnableStateMachineFactory + public static class Config3 extends EnumStateMachineConfigurerAdapter { + + @Override + public void configure(StateMachineConfigurationConfigurer config) throws Exception { + config + .withConfiguration() + .autoStartup(false); + } + + @Override + public void configure(StateMachineStateConfigurer states) throws Exception { + states + .withStates() + .initial(TestStates.S1) + .states(EnumSet.allOf(TestStates.class)); + } + + } + } diff --git a/spring-statemachine-core/src/test/java/org/springframework/statemachine/config/ConfigurationTests.java b/spring-statemachine-core/src/test/java/org/springframework/statemachine/config/ConfigurationTests.java index 17402652..ece26624 100644 --- a/spring-statemachine-core/src/test/java/org/springframework/statemachine/config/ConfigurationTests.java +++ b/spring-statemachine-core/src/test/java/org/springframework/statemachine/config/ConfigurationTests.java @@ -125,6 +125,17 @@ public class ConfigurationTests extends AbstractStateMachineTests { assertThat(machine.isRunning(), is(true)); } + @SuppressWarnings({ "unchecked" }) + @Test + public void testAutoStartFlagOff() throws Exception { + context.register(Config11.class); + context.refresh(); + ObjectStateMachine machine = + context.getBean(StateMachineSystemConstants.DEFAULT_ID_STATEMACHINE, ObjectStateMachine.class); + assertThat(machine.isAutoStartup(), is(false)); + assertThat(machine.isRunning(), is(false)); + } + @SuppressWarnings({ "unchecked" }) @Test public void testRegisterListeners() throws Exception { @@ -502,4 +513,25 @@ public class ConfigurationTests extends AbstractStateMachineTests { } + @Configuration + @EnableStateMachine + public static class Config11 extends EnumStateMachineConfigurerAdapter { + + @Override + public void configure(StateMachineConfigurationConfigurer config) throws Exception { + config + .withConfiguration() + .autoStartup(false); + } + + @Override + public void configure(StateMachineStateConfigurer states) throws Exception { + states + .withStates() + .initial(TestStates.S1) + .states(EnumSet.allOf(TestStates.class)); + } + + } + }