(1). 概述
在前一小节,对Spring StateMachine有了一个简单的了解,在这一小节,主要对源码进行剖析,那么剖析源码的入口在哪呢?
(2). 源码入口
@EnableStateMachine(name="orderSingleMachine")
(3). @EnableStateMachine
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@EnableAnnotationConfiguration
@Import({
StateMachineConfigurationImportSelector.class,
StateMachineCommonConfiguration.class,
// *******************************************************************
// 状态机配置类
// *******************************************************************
StateMachineConfiguration.class,
ObjectPostProcessorConfiguration.class })
@EnableWithStateMachine
public @interface EnableStateMachine {
// 配置状态机的名称,最后与@WithStateMachine(name="orderSingleMachine")中配置的名称一样.
String[] name() default {StateMachineSystemConstants.DEFAULT_ID_STATEMACHINE};
boolean contextEvents() default true;
}
(4). AbstractImportingAnnotationConfiguration(StateMachineConfiguration的父类)
public abstract class AbstractImportingAnnotationConfiguration<B extends AnnotationBuilder<O>, O> implements
ImportBeanDefinitionRegistrar, BeanFactoryAware, EnvironmentAware {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
// *****************************************************************
// 获得注解(@EnableStateMachine(name="orderSingleMachine")),挂在哪个类上面(help.lixin.config.StateMachineConfig)
// *****************************************************************
List<Class<? extends Annotation>> annotationTypes = getAnnotations();
Class<? extends Annotation> namedAnnotation = null;
// *****************************************************************
// 注解上的名称
// *****************************************************************
String[] names = null;
ScopedProxyMode proxyMode = null;
if (annotationTypes != null) {
for (Class<? extends Annotation> annotationType : annotationTypes) {
// 获得注解上的名称
AnnotationAttributes attributes = AnnotationAttributes.fromMap(importingClassMetadata.getAnnotationAttributes(annotationType.getName(), false));
if (attributes != null && attributes.containsKey("name")) {
names = attributes.getStringArray("name");
namedAnnotation = annotationType;
break;
}
}
}
// ... ...
BeanDefinition beanDefinition;
try {
// *****************************************************************
// 委托给子类StateMachineConfiguration处理.
// *****************************************************************
beanDefinition = buildBeanDefinition(importingClassMetadata, namedAnnotation);
} catch (Exception e) {
throw new RuntimeException("Error with onConfigurers", e);
}
// implementation didn't return definition so don't continue registration
if (beanDefinition == null) {
return;
}
if (ObjectUtils.isEmpty(names)) {
// ok, name(s) not given, generate one
names = new String[] { beanNameGenerator.generateBeanName(beanDefinition, registry) };
}
// **************************************************************************************************
// @EnableStateMachine(name="orderSingleMachine")
// 向Spring容器中注册Bean,Bean名称为:orderSingleMachine,对应的Bean为:StateMachineDelegatingFactoryBean
// **************************************************************************************************
registry.registerBeanDefinition(names[0], beanDefinition);
// ... ...
} // end registerBeanDefinitions
}
(5). StateMachineConfiguration
@Configuration
public class StateMachineConfiguration<S, E> extends
AbstractImportingAnnotationConfiguration<StateMachineConfigBuilder<S, E>, StateMachineConfig<S, E>> {
@Override
protected BeanDefinition buildBeanDefinition(AnnotationMetadata importingClassMetadata, Class<? extends Annotation> namedAnnotation) throws Exception {
String enableStateMachineEnclosingClassName = importingClassMetadata.getClassName();
// for below classloader, see gh122
Class<?> enableStateMachineEnclosingClass = ClassUtils.forName(enableStateMachineEnclosingClassName,ClassUtils.getDefaultClassLoader());
// return null if it looks like @EnableStateMachine was annotated with class
// not extending StateMachineConfigurer.
if (!ClassUtils.isAssignable(StateMachineConfigurer.class, enableStateMachineEnclosingClass)) {
return null;
}
// **************************************************************************************************
// StateMachineDelegatingFactoryBean是状态机的装饰工厂.
// **************************************************************************************************
BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.rootBeanDefinition(StateMachineDelegatingFactoryBean.class);
AnnotationAttributes esmAttributes = AnnotationAttributes.fromMap(importingClassMetadata.getAnnotationAttributes(EnableStateMachine.class.getName(), false));
Boolean contextEvents = esmAttributes.getBoolean("contextEvents");
// check if Scope annotation is defined and set scope from it
AnnotationAttributes scopeAttributes = AnnotationAttributes.fromMap(importingClassMetadata.getAnnotationAttributes(Scope.class.getName(), false));
if (scopeAttributes != null) {
String scope = scopeAttributes.getString("value");
if (StringUtils.hasText(scope)) {
beanDefinitionBuilder.setScope(scope);
}
}
// *******************************************************************
// *******************************************************************
// 为StateMachineDelegatingFactoryBean配置构建器:
// 1. 创建一个空的状态机构造器.
// StateMachineConfigBuilder<S, E> builder
// 2. 真实的状态机
// Class<StateMachine<S, E>> clazz = StateMachine.class
// String clazzName = help.lixin.StateMachineConfig
// 3. 是否开启上下文事件.
// Boolean contextEvents = true
beanDefinitionBuilder.addConstructorArgValue(builder);
beanDefinitionBuilder.addConstructorArgValue(StateMachine.class);
beanDefinitionBuilder.addConstructorArgValue(importingClassMetadata.getClassName());
beanDefinitionBuilder.addConstructorArgValue(contextEvents);
AbstractBeanDefinition beanDefinition = beanDefinitionBuilder.getBeanDefinition();
// try to add more info about generics
ResolvableType type = resolveFactoryObjectType(enableStateMachineEnclosingClass);
if (type != null && beanDefinition instanceof RootBeanDefinition) {
((RootBeanDefinition)beanDefinition).setTargetType(type);
}
return beanDefinition;
} // end buildBeanDefinition
}
(6). 总结
注解:@EnableStateMachine(name=”orderSingleMachine”)会向Spring容器中注册一个Bean,Bean的名称为:orderSingleMachine,类型为:StateMachineDelegatingFactoryBean.