diff --git a/docs/src/info/changelog.txt b/docs/src/info/changelog.txt index a257d930..0750559c 100644 --- a/docs/src/info/changelog.txt +++ b/docs/src/info/changelog.txt @@ -8,6 +8,7 @@ Changes in version 1.1.0.M2 (2016-03-21) ---------------------------------------- * Better config error handling [#103] * Support testing intermediate state changes [#154] +* Document spring javaconfig usage for beans [#162] * Listener error should not cause malfunction [#164] * Timer interval reset for states [#165] * Make config data classes as a public api [#172] diff --git a/docs/src/reference/asciidoc/sm.adoc b/docs/src/reference/asciidoc/sm.adoc index ec1db3f6..c175c6a6 100644 --- a/docs/src/reference/asciidoc/sm.adoc +++ b/docs/src/reference/asciidoc/sm.adoc @@ -346,6 +346,34 @@ include::samples/DocsConfigurationSampleTests.java[tags=snippetYC] More about config model, refer to section <>. +[[statemachine-config-thingstoremember]] +=== Things to Remember + +When defining actions, guards or any other references from a +configuration there are things to remember how Spring Framework works +with beans. In below we have defined a normal configuration with +states `S1` and `S2` and 4 transitions between those. All transitions +are either guarded by `guard1` or `guard2`. Pay attention that +`guard1` is created as a real bean because it's annotated with a +_@Bean_, while `guard2` is not. + +What this mean is that event `E3` would get `guard2` condition as +`TRUE` and `E4` would get `guard2` condition as `FALSE` as those are +simply coming from a plain method calls to those functions. + +However because `guard1` is defined as a _@Bean_, it is proxied by a +Spring Framework, thus additional calls to its method will result +only one instantiation of that instance. Event `E1` would get first +proxied instance with condition `TRUE` while event `E2` would get same +instance with `TRUE` condition while method call was defined with +`FALSE`. This is not a Spring State Machine specific behaviour, it's +just how Spring Framework works with _Beans_. + +[source,java,indent=0] +---- +include::samples/DocsConfigurationSampleTests7.java[tags=snippetA] +---- + [[sm-factories]] == State Machine Factories There are use cases when state machine needs to be created dynamically diff --git a/spring-statemachine-core/src/test/java/org/springframework/statemachine/docs/DocsConfigurationSampleTests7.java b/spring-statemachine-core/src/test/java/org/springframework/statemachine/docs/DocsConfigurationSampleTests7.java new file mode 100644 index 00000000..b525b232 --- /dev/null +++ b/spring-statemachine-core/src/test/java/org/springframework/statemachine/docs/DocsConfigurationSampleTests7.java @@ -0,0 +1,82 @@ +/* + * Copyright 2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.statemachine.docs; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.statemachine.StateContext; +import org.springframework.statemachine.config.EnableStateMachine; +import org.springframework.statemachine.config.StateMachineConfigurerAdapter; +import org.springframework.statemachine.config.builders.StateMachineStateConfigurer; +import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer; +import org.springframework.statemachine.guard.Guard; + +public class DocsConfigurationSampleTests7 { + +// tag::snippetA[] + @Configuration + @EnableStateMachine + public class Config1 + extends StateMachineConfigurerAdapter { + + @Override + public void configure(StateMachineStateConfigurer states) + throws Exception { + states + .withStates() + .initial("S1") + .state("S2"); + } + + @Override + public void configure(StateMachineTransitionConfigurer transitions) + throws Exception { + transitions + .withExternal() + .source("S1").target("S2").event("E1").guard(guard1(true)) + .and() + .withExternal() + .source("S1").target("S2").event("E2").guard(guard1(false)) + .and() + .withExternal() + .source("S1").target("S2").event("E3").guard(guard2(true)) + .and() + .withExternal() + .source("S1").target("S2").event("E4").guard(guard2(false)); + } + + @Bean + public Guard guard1(final boolean value) { + return new Guard() { + @Override + public boolean evaluate(StateContext context) { + return value; + } + }; + } + + public Guard guard2(final boolean value) { + return new Guard() { + @Override + public boolean evaluate(StateContext context) { + return value; + } + }; + } + } +// end::snippetA[] + +}