在上一篇《Spring Statemachine使用入门》中,我们使用过了StateMachineBuilder的内部类Builder创建了一个StateMachine对象,接下来我们具体来分析一下使用StateMachineBuilder.Builder创建状态机的具体过程。
StateMachineBuilder只有一个方法builder()并且没有任何成员变量,builder()方法返回一个StateMachineBuilder内部类Builder对象。

在Builder的构造方法中实例化了两个对象:StateMachineConfigBuilder和BuilderStateMachineConfigurerAdapter,而StateMachine的创建是在build()方法中。build()方法中用到了这两个对象,下面就先来看看StateMachineConfigBuilder,build()方法其余步骤后面再讲。


1、AnnotationBuilder:定义创建对象的方法
StateMachineConfigBuilder从类名可以猜出这是一个用来构造StateMachineConfig的辅助类,StateMachineConfigBuilder的顶级接口是AnnotationBuilder,这个接口只有一个方法用来构建并返回一个对象。
public interface AnnotationBuilder<O> {
O build() throws Exception;
}
其实这个AnnotationBuilder接口有多个实现类,AnnotationBuilder的类结构体系是一个四层结构,底层有5个实现类,每个实现类类负责创建构造状态机对象的一类对象。如StateMachineModelBuilder用来构建ModelData对象的。

1.1、AbstractAnnotationBuilder:确保对象只创建一次
AbstractAnnotationBuilder是AnnotationBuilder的抽象实现类,这个抽象类实现了build()方法,通过对AtomicBoolean的cas操作确保doBuild()方法只被调用一次。
/** Flag tracking build */
private AtomicBoolean building = new AtomicBoolean();
/** Built object is stored here */
private O object;
@Override
public final O build() throws Exception {
if(building.compareAndSet(false, true)) {
object = doBuild();
return object;
}
throw new IllegalStateException("This object has already been built");
}
protected abstract O doBuild() throws Exception;
1.2、AbstractConfiguredAnnotationBuilder:提供对自身进行配置的功能
AbstractConfiguredAnnotationBuilder提供了apply()方法使用接口AnnotationConfigurer实例对其进行配置的方式。这使得修改AnnotationBuilder成为一种策略,可以对其进行自定义。
public <C extends AnnotationConfigurer<O, B>> C apply(C configurer) throws Exception {
add(configurer);
return configurer;
}
private <C extends AnnotationConfigurer<O, B>> void add(C configurer) throws Exception {
Assert.notNull(configurer, "configurer cannot be null");
Class<? extends AnnotationConfigurer<O, B>> clazz =
(Class<? extends AnnotationConfigurer<O, B>>) configurer.getClass();
//如果当前构建状态在调用AnnotationConfigurer.configure()方法前
if (!buildState.isConfigured()) {
synchronized (mainConfigurers) {
//允许有相同类型的多个AnnotationConfigurer则configurer直接追加到原有链表中
//否则替换原有相同类型的AnnotationConfigurer,默认值为false
List<AnnotationConfigurer<O, B>> configs = allowConfigurersOfSameType ? this.mainConfigurers.get(clazz) : null;
if (configs == null) {
configs = new ArrayList<AnnotationConfigurer<O, B>>(1);
}
configs.add(configurer);
this.mainConfigurers.put(clazz, configs);
//如果在调用AnnotationConfigurer.init()时直接进行初始化方法调用
if (buildState.isInitializing()) {
configurer.init((B) this);
}
}
} else {
synchronized (postConfigurers) {
List<AnnotationConfigurer<O, B>> configs = allowConfigurersOfSameType ? this.postConfigurers.get(clazz) : null;
if (configs == null) {
configs = new ArrayList<AnnotationConfigurer<O, B>>(1);
}
configs.add(configurer);
this.postConfigurers.put(clazz, configs);
configurer.init((B) this);
}
}
}
上面这个apply方法接收一个AnnotationConfigurer类型的参数,然后通过add方法将这个configurer加入到链表mainConfigurers或postConfigurers中,至于加入到哪个链表中取决于apply()方法在哪个阶段配调用的。AbstractConfiguredAnnotationBuilder内部定义了一个枚举类,用来表示AnnotationBuilder构建对象的过程中所处于的状态,共有6种状态如下。!buildState.isConfigured()表示如果当前构建状态在CONFIGURING_MAINS之前就会将参数configurer表示的AnnotationConfigurer加入到mainConfigurers链表中否则加入到链表postConfigurers中。
buildState的状态流转发生在doBuild()方法,AbstractConfiguredAnnotationBuilder实现的doBuild()方法如下:
@Override
protected final O doBuild() throws Exception {
synchronized (mainConfigurers) {
buildState = BuildState.INITIALIZING_MAINS;
beforeInit(); //空实现
initMainConfigurers(); //调用mainConfigurers中的init(this)方法对自身进行初始化配置
buildState = BuildState.CONFIGURING_MAINS;
beforeConfigureMains(); //空实现
configureMainConfigurers();//调用mainConfigurers中的configure(this)方法对自身进行配置
buildState = BuildState.CONFIGURING_POSTS;
beforeConfigurePosts(); //空实现
configurePostConfigurers();//调用postConfigurers中的configure(this)方法对自身进行配置
buildState = BuildState.BUILDING;
O result = performBuild();//由具体子类实现
buildState = BuildState.BUILT;
return result;
}
}
除了使用上面提到的apply()方法对 AnnotationBuilder进行配置外,AbstractConfiguredAnnotationBuilder还提供了一个重载方法用来配置自身。
public <C extends AnnotationConfigurerAdapter<O,I,B>> C apply(C configurer) throws Exception {
add(configurer);
configurer.addObjectPostProcessor(objectPostProcessor);
//每个AnnotationConfigurerAdapter对象都持有当前配置的AnnotationBuilder对象的引用
configurer.setBuilder((B) this);
return configurer;
}
AnnotationConfigurerAdapter是AnnotationConfigurer的适配器实现,真对于配置不同的AnnotationBuilder的AnnotationConfigurer差异化实现都可通过集成AnnotationConfigurerAdapter然后实现差异化接口实现,如DefaultModelConfigurer:

AbstractConfiguredAnnotationBuilder最后留了一个抽象方法performBuild交由子类实现,这个方法就是最终创建对象的地方。
在分析子类实现的performBuild的方法之前先来看另一个相关的方法getSharedObject()方法:
public <C> C getSharedObject(Class<C> sharedType) {
return (C) this.sharedObjects.get(sharedType);
}
sharedObjects是一个Map<Class<Object>, Object>类型的数据结构,通过调用setSharedObject方法填充元素,至于这个sharedObjects是存放什么数据的,下面介绍。
1.3、StateMachineConfigBuilder创建StateMachineConfig
AbstractConfiguredAnnotationBuilder的实现类共有5个,这里先分析StateMachineBuilder.Builder中的StateMachineConfigBuilder。
public class StateMachineConfigBuilder<S, E>
extends
AbstractConfiguredAnnotationBuilder<StateMachineConfig<S, E>, StateMachineConfigBuilder<S, E>, StateMachineConfigBuilder<S, E>> {
@SuppressWarnings("unchecked")
@Override
protected StateMachineConfig<S, E> performBuild() throws Exception {
// TODO: should prevent calling state/transition builder if model is given
StateMachineModelBuilder<?, ?> modelBuilder = getSharedObject(StateMachineModelBuilder.class);
StateMachineConfigurationBuilder<?, ?> configurationBuilder = getSharedObject(StateMachineConfigurationBuilder.class);
StateMachineTransitionBuilder<?, ?> transitionBuilder = getSharedObject(StateMachineTransitionBuilder.class);
StateMachineStateBuilder<?, ?> stateBuilder = getSharedObject(StateMachineStateBuilder.class);
ModelData<S, E> model = (ModelData<S, E>) modelBuilder.build();
ConfigurationData<S, E> stateMachineConfigurationConfig = null;
stateMachineConfigurationConfig = (ConfigurationData<S, E>) configurationBuilder.build();
transitionBuilder.setSharedObject(ConfigurationData.class, stateMachineConfigurationConfig);
TransitionsData<S, E> transitions = (TransitionsData<S, E>) transitionBuilder.build();
StatesData<S, E> states = (StatesData<S, E>) stateBuilder.build();
return new StateMachineConfig<S, E>(stateMachineConfigurationConfig, transitions, states, model);
}
}
在performBuild()方法中new了一个StateMachineConfig返回,而这个StateMachineConfig的几个构造参数都是通过调用父类方法getSharedObject()得到相应构造参数对象的builder对象,然后调用builder对象的build方法创建的对象。
默认sharedObjects内元素为空,那么什么时候往里填充数据的呢?
在Spring StateMachine中默认提供的类中,在这两个地方会调用StateMachineConfigBuilder的setSharedObject方法。
- BuilderStateMachineConfigurerAdapter in StateMachineBuilder.init(StateMachineConfigBuilder)
- AbstractStateMachineConfigurerAdapter.init(StateMachineConfigBuilder)
下面是上面第一个地方的实现:
BuilderStateMachineConfigurerAdapter() {
try {
getStateMachineModelBuilder();
getStateMachineTransitionBuilder();
getStateMachineStateBuilder();
getStateMachineConfigurationBuilder();
} catch (Exception e) {
throw new StateMachineException("Error instantiating builder adapter", e);
}
}
@Override
public void init(StateMachineConfigBuilder<S, E> config) throws Exception {
config.setSharedObject(StateMachineModelBuilder.class, getStateMachineModelBuilder());
config.setSharedObject(StateMachineTransitionBuilder.class, getStateMachineTransitionBuilder());
config.setSharedObject(StateMachineStateBuilder.class, getStateMachineStateBuilder());
config.setSharedObject(StateMachineConfigurationBuilder.class, getStateMachineConfigurationBuilder());
}
在构造方法中实例化了这四个builder对象,然后当在AnnotationBuilder的apply方法调用时触发BuilderStateMachineConfigurerAdapter的init方法为StateMachineConfigBuilder设置这四个builder对象。
下面是getStateMachineModelBuilder()的实现,其余三个一样。
protected final StateMachineModelBuilder<S, E> getStateMachineModelBuilder() throws Exception {
if (modelBuilder != null) {
return modelBuilder;
}
modelBuilder = new StateMachineModelBuilder<S, E>(ObjectPostProcessor.QUIESCENT_POSTPROCESSOR, true);
configure(modelBuilder);//空实现
return modelBuilder;
}
2、AnnotationConfigurer:用来配置AnnotationBuilder
通过上面对接口AnnotationBuilder及其实现类StateMachineModelBuilder的源码走读了解到相应的AnnotationConfigurer实现类通过init和configure方法配置对应的AnnotationBuilder实现类。
所有AnnotationConfigurer首先调用其init(AnnotationBuilder)方法。调用所有init方法后,将调用每个configure(AnnotationBuilder)方法。

顶级接口AnnotationConfigurer定义了三个方法:
public interface AnnotationConfigurer<O, B extends AnnotationBuilder<O>> {
/**
* 初始化AnnotationBuilder。在这里,只应创建和修改共享状态,
* 而不应在用于生成对象的AnnotationBuilder上创建和修改属性。
* 这样可以确保configure方法在生成时使用正确的共享对象
*/
void init(B builder) throws Exception;
/**
* 通过在AnnotationBuilder上设置必要的特性来配置AnnotationBuilder
*/
void configure(B builder) throws Exception;
/**
* 是否可以用于配置这个builder
*/
boolean isAssignable(AnnotationBuilder<O> builder);
}
上一节中我们已经看过了BuilderStateMachineConfigurerAdapter的实现了,下面我们来看一下其余实现类。
2.1、AnnotationConfigurerAdapter:AnnotationConfigurer的增强适配器
AnnotationConfigurerAdapter默认实现了AnnotationConfigurer的三个方法,并额外提供了几个方法增强自身功能。
builder的setter和getter方法:getter方法可以方便的获取配置的AnnotationBuilder,setter方法我们之前已经看到过了,这里在回顾一下如下图。

and方法:使用AnnotationConfigurer完成后返回AnnotationBuilder。这对于方法链接很有用。
public I and() {
// we're either casting to itself or its interface
return (I) getBuilder();
}
addObjectPostProcessor方法:添加用于此适配器的ObjectPostProcessor。默认实现对对象没有任何作用。
public void addObjectPostProcessor(ObjectPostProcessor<?> objectPostProcessor) {
this.objectPostProcessor.addObjectPostProcessor(objectPostProcessor);
}
this.objectPostProcessor具体类型是一个内部类CompositeObjectPostProcessor可用于组合通过addObjectPostProcessor方法添加进来的ObjectPostProcessor对象。
private static final class CompositeObjectPostProcessor implements ObjectPostProcessor<Object> {
private List<ObjectPostProcessor<? extends Object>> postProcessors = new ArrayList<ObjectPostProcessor<?>>();
@Override
public Object postProcess(Object object) {
for(ObjectPostProcessor opp : postProcessors) {
Class<?> oppClass = opp.getClass();
Class<?> oppType = GenericTypeResolver.resolveTypeArgument(oppClass,ObjectPostProcessor.class);
if(oppType == null || oppType.isAssignableFrom(object.getClass())) {
object = opp.postProcess(object);
}
}
return object;
}
private boolean addObjectPostProcessor(ObjectPostProcessor<? extends Object> objectPostProcessor) {
return this.postProcessors.add(objectPostProcessor);
}
}
2.2、AnnotationConfigurerAdapter的子类
通过1.2节的类图可知AnnotationConfigurerAdapter的子类众多,图中只是其中一小部分实现类,每种实现类配置一种AnnotationBuilder,并且还额外实现了其余的接口如DefaultStateConfigurer实现了StateConfigurer接口。

这里暂只讲解AnnotationConfigurer的子接口StateConfigurer的实现类DefaultStateConfigurer,待到后面具体用到再做具体分析,这里只需要弄清楚这些子类是如何被应用的即可。
2.2.1、DefaultStateConfigurer
这里先回顾上一篇文章《Spring Statemachine使用入门》的代码:

这里配置状态机的状态时通过调用builder.configureStates().withStates()返回的StateConfigurer对其进行配置的:
builder.configureStates()方法返回的就是StateMachineBuilder内部类Builder持有的adapter成员变量的,可以回顾一下本文开头部分和1.1.3节的内容。
public Builder() {
adapter = new BuilderStateMachineConfigurerAdapter<S, E>();
builder = new StateMachineConfigBuilder<S, E>();
}
public StateMachineStateConfigurer<S, E> configureStates() {
return adapter.stateBuilder;
}

StateMachineStateBuilder实现了StateMachineStateConfigurer接口,这个接口只有一个方法:
@Override
public StateConfigurer<S, E> withStates() throws Exception {
return apply(new DefaultStateConfigurer<S, E>());
}
当调用withStates()方法时其实就是调用了apply方法传入了一个DefaultStateConfigurer对自身做一个初始配置,并返回这个DefaultStateConfigurer对象,然后调用这个对象的配置方法.initial(States.STATE1).states(EnumSet.allOf(States.class))做一些自定义配置。
下面看一下DefaultStateConfigurer的实现:
public void configure(StateMachineStateBuilder<S, E> builder) throws Exception {
// before passing state datas to builder, update structure
// for missing parent, initial and end state infos.
Collection<StateData<S, E>> stateDatas = new ArrayList<StateData<S, E>>();
for (StateData<S, E> s : incomplete.values()) {
s.setParent(parent);
stateDatas.add(s);
if (s.getState() == initialState) {
s.setInitial(true);
s.setInitialAction(initialAction);
}
if (ends.contains(s.getState())) {
s.setEnd(true);
}
if (choices.contains(s.getState())) {
s.setPseudoStateKind(PseudoStateKind.CHOICE);
} else if (junctions.contains(s.getState())) {
s.setPseudoStateKind(PseudoStateKind.JUNCTION);
} else if (forks.contains(s.getState())) {
s.setPseudoStateKind(PseudoStateKind.FORK);
} else if (joins.contains(s.getState())) {
s.setPseudoStateKind(PseudoStateKind.JOIN);
} else if (entrys.contains(s.getState())) {
s.setPseudoStateKind(PseudoStateKind.ENTRY);
} else if (exits.contains(s.getState())) {
s.setPseudoStateKind(PseudoStateKind.EXIT);
}
if (s.getState() == history) {
if (History.SHALLOW == historyType) {
s.setPseudoStateKind(PseudoStateKind.HISTORY_SHALLOW);
} else if (History.DEEP == historyType) {
s.setPseudoStateKind(PseudoStateKind.HISTORY_DEEP);
}
}
s.setSubmachine(submachines.get(s.getState()));
s.setSubmachineFactory(submachinefactories.get(s.getState()));
}
builder.addStateData(stateDatas);
}
上面configure方法将incomplete中保存的StateData根据不同的状态类型设置对应的pseudoStateKind属性值,然后通过builder.addStateData()方法放入到StateMachineStateBuilder的stateDatas中,然后在performBuild方法调用时会使用到这个stateDatas封装到一个StatesData对象中。
@Override
protected StatesData<S, E> performBuild() throws Exception {
return new StatesData<S, E>(stateDatas);
}
public void addStateData(Collection<StateData<S, E>> stateDatas) {
this.stateDatas.addAll(stateDatas);
}
incomplete是一个Map的数据结构,当调用StateConfigurer的方法时会对其进行填充,如initial方法:
@Override
public StateConfigurer<S, E> initial(S initial) {
this.initialState = initial;
state(initial);
return this;
}
public StateConfigurer<S, E> state(S state, E... deferred) {
Collection<E> d = null;
if (deferred != null) {
d = Arrays.asList(deferred);
}
addIncomplete(null, state, d, null, null, null);
return this;
}
private void addIncomplete(Object parent, S state, Collection<E> deferred,
Collection<? extends Action<S, E>> entryActions, Collection<? extends Action<S, E>> exitActions,
Collection<? extends Action<S, E>> stateActions) {
StateData<S, E> stateData = incomplete.get(state);
if (stateData == null) {
stateData = new StateData<S, E>(parent, region, state, deferred, entryActions, exitActions);
incomplete.put(state, stateData);
}
if (stateData.getParent() == null) {
stateData.setParent(parent);
}
if (stateData.getRegion() == null) {
stateData.setRegion(region);
}
if (stateData.getDeferred() == null) {
stateData.setDeferred(deferred);
}
if (stateData.getEntryActions() == null) {
stateData.setEntryActions(entryActions);
}
if (stateData.getExitActions() == null) {
stateData.setExitActions(exitActions);
}
if (stateData.getStateActions() == null) {
stateData.setStateActions(stateActions);
}
}
3、StateMachineFactory:创建虚拟机
状态机的创建是通过这个工厂实现的,而工厂需要的原料就是上面说的AnnotationBuilder是用来创建的对象,其中StateMachineConfig是对ConfigurationData、TransitionsData、StatesData、ModelData四种原料的组合包装。
public interface StateMachineFactory<S, E> {
StateMachine<S, E> getStateMachine();
StateMachine<S, E> getStateMachine(String machineId);
StateMachine<S, E> getStateMachine(UUID uuid);
}
StateMachineFactory定义了三个创建状态机方法,子类AbstractStateMachineFactory实现了这个三个方法。

3.1、AbstractStateMachineFactory
AbstractStateMachineFactory中实现了获取StateMachine的方法,
public StateMachine<S, E> getStateMachine(UUID uuid, String machineId) {
ArrayList<StateMachine<S, E>> machines = new ArrayList<>();
//通过StateMachineModelBuilder配置的StateMachineModelFactory得到一个StateMachineModel,
StateMachineModel<S, E> stateMachineModel = resolveStateMachineModel(machineId);
if (stateMachineModel.getConfigurationData().isVerifierEnabled()) {
StateMachineModelVerifier<S, E> verifier = stateMachineModel.getConfigurationData().getVerifier();
if (verifier == null) {
verifier = new CompositeStateMachineModelVerifier<S, E>();
}
verifier.verify(stateMachineModel);
}
// shared
DefaultExtendedState defaultExtendedState = new DefaultExtendedState();
StateMachine<S, E> machine = null;
// we store mappings from state id's to states which gets
// created during the process. This is needed for transitions to
// find a correct mappings because they use state id's, not actual
// states.
final Map<S, State<S, E>> stateMap = new HashMap<S, State<S, E>>();
Stack<MachineStackItem<S, E>> regionStack = new Stack<MachineStackItem<S, E>>();
Stack<StateData<S, E>> stateStack = new Stack<StateData<S, E>>();
Map<Object, StateMachine<S, E>> machineMap = new HashMap<Object, StateMachine<S,E>>();
List<HolderListItem<S, E>> holderList = new ArrayList<>();
Iterator<Node<StateData<S, E>>> iterator = buildStateDataIterator(stateMachineModel);
while (iterator.hasNext()) {
Node<StateData<S, E>> node = iterator.next();
StateData<S, E> stateData = node.getData();
StateData<S, E> peek = stateStack.isEmpty() ? null : stateStack.peek();
// simply push and continue
if (stateStack.isEmpty()) {
stateStack.push(stateData);
continue;
}
boolean stackContainsSameParent = false;
Iterator<StateData<S, E>> ii = stateStack.iterator();
while (ii.hasNext()) {
StateData<S, E> sd = ii.next();
if (stateData != null && ObjectUtils.nullSafeEquals(stateData.getState(), sd.getParent())) {
stackContainsSameParent = true;
break;
}
}
if (stateData != null && !stackContainsSameParent) {
stateStack.push(stateData);
continue;
}
Collection<StateData<S, E>> stateDatas = popSameParents(stateStack);
int initialCount = getInitialCount(stateDatas);
Collection<Collection<StateData<S, E>>> regionsStateDatas = splitIntoRegions(stateDatas);
Collection<TransitionData<S, E>> transitionsData = getTransitionData(iterator.hasNext(), stateDatas, stateMachineModel);
if (initialCount > 1) {
for (Collection<StateData<S, E>> regionStateDatas : regionsStateDatas) {
// try to build reqion id's
Object rId = regionStateDatas.iterator().next().getRegion();
String mId = machineId != null ? machineId : stateMachineModel.getConfigurationData().getMachineId();
mId = mId + "#" + (rId != null ? rId.toString() : "");
machine = buildMachine(machineMap, stateMap, holderList, regionStateDatas, transitionsData,
resolveBeanFactory(stateMachineModel), contextEvents, defaultExtendedState,
stateMachineModel.getTransitionsData(), mId, null, stateMachineModel);
regionStack.push(new MachineStackItem<S, E>(machine));
machines.add(machine);
}
Collection<Region<S, E>> regions = new ArrayList<Region<S, E>>();
while (!regionStack.isEmpty()) {
MachineStackItem<S, E> pop = regionStack.pop();
regions.add(pop.machine);
}
S parent = (S)peek.getParent();
RegionState<S, E> rstate = buildRegionStateInternal(parent, regions, null,
stateData != null ? stateData.getEntryActions() : null,
stateData != null ? stateData.getExitActions() : null,
new DefaultPseudoState<S, E>(PseudoStateKind.INITIAL), stateMachineModel);
rstate.setRegionExecutionPolicy(stateMachineModel.getConfigurationData().getRegionExecutionPolicy());
if (stateData != null) {
stateMap.put(stateData.getState(), rstate);
} else {
// TODO: don't like that we create a last machine here
Collection<State<S, E>> states = new ArrayList<State<S, E>>();
states.add(rstate);
Transition<S, E> initialTransition = new InitialTransition<S, E>(rstate);
StateMachine<S, E> m = buildStateMachineInternal(states, new ArrayList<Transition<S, E>>(), rstate, initialTransition,
null, defaultExtendedState, null, contextEvents, resolveBeanFactory(stateMachineModel), beanName,
machineId != null ? machineId : stateMachineModel.getConfigurationData().getMachineId(),
uuid, stateMachineModel);
machine = m;
machines.add(m);
}
} else {
machine = buildMachine(machineMap, stateMap, holderList, stateDatas, transitionsData,
resolveBeanFactory(stateMachineModel), contextEvents, defaultExtendedState,
stateMachineModel.getTransitionsData(), machineId, uuid, stateMachineModel);
machines.add(machine);
if (peek.isInitial() || (!peek.isInitial() && !machineMap.containsKey(peek.getParent()))) {
machineMap.put(peek.getParent(), machine);
}
}
stateStack.push(stateData);
}
// setup autostart for top-level machine
if (machine instanceof LifecycleObjectSupport) {
((LifecycleObjectSupport)machine).setAutoStartup(stateMachineModel.getConfigurationData().isAutoStart());
}
// set top-level machine as relay
final StateMachine<S, E> fmachine = machine;
fmachine.getStateMachineAccessor().doWithAllRegions(function -> function.setRelay(fmachine));
// add monitoring hooks
final StateMachineMonitor<S, E> stateMachineMonitor = stateMachineModel.getConfigurationData().getStateMachineMonitor();
if (stateMachineMonitor != null || defaultStateMachineMonitor != null) {
fmachine.getStateMachineAccessor().doWithRegion(function -> {
if (defaultStateMachineMonitor != null) {
function.addStateMachineMonitor(defaultStateMachineMonitor);
}
if (stateMachineMonitor != null) {
function.addStateMachineMonitor(stateMachineMonitor);
}
});
}
// set parent machines for each built machine
for (Entry<Object, StateMachine<S, E>> mme : machineMap.entrySet()) {
StateMachine<S, E> m = null;
if (mme.getKey() != null) {
Object sParent = null;
for (StateData<S, E> sd : stateMachineModel.getStatesData().getStateData()) {
if (ObjectUtils.nullSafeEquals(sd.getState(), mme.getKey())) {
sParent = sd.getParent();
break;
}
}
m = machineMap.get(sParent);
}
final StateMachine<S, E> mm = m;
mme.getValue().getStateMachineAccessor().doWithRegion(function -> function.setParentMachine(mm));
}
// init built machines
for (StateMachine<S, E> m : machines) {
((LifecycleObjectSupport)m).afterPropertiesSet();
}
// TODO: should error out if sec is enabled but spring-security is not in cp
if (stateMachineModel.getConfigurationData().isSecurityEnabled()) {
final StateMachineSecurityInterceptor<S, E> securityInterceptor = new StateMachineSecurityInterceptor<S, E>(
stateMachineModel.getConfigurationData().getTransitionSecurityAccessDecisionManager(),
stateMachineModel.getConfigurationData().getEventSecurityAccessDecisionManager(),
stateMachineModel.getConfigurationData().getEventSecurityRule());
log.info("Adding security interceptor " + securityInterceptor);
fmachine.getStateMachineAccessor()
.doWithAllRegions(function -> function.addStateMachineInterceptor(securityInterceptor));
}
// setup distributed state machine if needed.
// we wrap previously build machine with a distributed
// state machine and set it to use given ensemble.
if (stateMachineModel.getConfigurationData().getStateMachineEnsemble() != null) {
DistributedStateMachine<S, E> distributedStateMachine = new DistributedStateMachine<S, E>(
stateMachineModel.getConfigurationData().getStateMachineEnsemble(), machine);
distributedStateMachine.setAutoStartup(stateMachineModel.getConfigurationData().isAutoStart());
distributedStateMachine.afterPropertiesSet();
machine = distributedStateMachine;
}
for (StateMachineListener<S, E> listener : stateMachineModel.getConfigurationData().getStateMachineListeners()) {
machine.addStateListener(listener);
}
List<StateMachineInterceptor<S,E>> interceptors = stateMachineModel.getConfigurationData().getStateMachineInterceptors();
if (interceptors != null) {
for (final StateMachineInterceptor<S, E> interceptor : interceptors) {
// add persisting interceptor hooks to all regions
RegionPersistingInterceptorAdapter<S, E> adapter = new RegionPersistingInterceptorAdapter<>(interceptor, machine);
machine.getStateMachineAccessor().doWithAllRegions(function -> function.addStateMachineInterceptor(adapter));
}
}
// go through holders and fix state references which
// were not known at a time holder was created
for (HolderListItem<S, E> holderItem : holderList) {
holderItem.value.setState(stateMap.get(holderItem.key));
}
return delegateAutoStartup(machine);
}
本文详细解析了 Spring StateMachine 的构建流程,包括 AnnotationBuilder 和 AnnotationConfigurer 的使用,以及状态机配置对象 StateMachineConfig 的创建过程。
1684

被折叠的 条评论
为什么被折叠?



