(1). 概述
在这一小篇,主要了解:ProcessEngineConfigurationImpl的初始化,在了解该类之前,我们要先了解一个接口:ProcessEnginePlugin.
(2). ProcessEnginePlugin接口能力
public interface ProcessEnginePlugin {
// 创建ProcessEngine之前,调用:preInit方法,允许对:ProcessEngineConfigurationImpl进行扩展.
void preInit(ProcessEngineConfigurationImpl processEngineConfiguration);
// 创建ProcessEngine后,调用:postInit方法,允许对:ProcessEngineConfigurationImpl进行扩展.
void postInit(ProcessEngineConfigurationImpl processEngineConfiguration);
// 在生成ProcessEngine实例后,调用方法.
void postProcessEngineBuild(ProcessEngine processEngine);
}
(3). CamundaBpmConfiguration配置类
public class CamundaBpmConfiguration {
// ********************************************************************************************
// 2. 创建:ProcessEngineConfigurationImpl对象
// ********************************************************************************************
@Bean
@ConditionalOnMissingBean(ProcessEngineConfigurationImpl.class)
public ProcessEngineConfigurationImpl processEngineConfigurationImpl(
// ****************************************************************************************
// 2. ProcessEngineConfigurationImpl的创建依赖于:ProcessEnginePlugin的实现
// CompositeProcessEnginePlugin典型的组合模式哈
// ****************************************************************************************
List<ProcessEnginePlugin> processEnginePlugins) {
final SpringProcessEngineConfiguration configuration = CamundaSpringBootUtil.springProcessEngineConfiguration();
configuration.getProcessEnginePlugins().add(new CompositeProcessEnginePlugin(processEnginePlugins));
return configuration;
}
// ********************************************************************************************
// 1. CamundaProcessEngineConfiguration实际为:ProcessEnginePlugin接口的实现
// ********************************************************************************************
@Bean
@ConditionalOnMissingBean(DefaultProcessEngineConfiguration.class)
public static CamundaProcessEngineConfiguration camundaProcessEngineConfiguration() {
return new DefaultProcessEngineConfiguration();
}
@Bean
@ConditionalOnMissingBean(CamundaDatasourceConfiguration.class)
public static CamundaDatasourceConfiguration camundaDatasourceConfiguration() {
return new DefaultDatasourceConfiguration();
}
@Bean
@ConditionalOnBean(name = "entityManagerFactory")
@ConditionalOnMissingBean(CamundaJpaConfiguration.class)
@ConditionalOnProperty(prefix = "camunda.bpm.jpa", name = "enabled", havingValue = "true", matchIfMissing = true)
public static CamundaJpaConfiguration camundaJpaConfiguration() {
return new DefaultJpaConfiguration();
}
@Bean
@ConditionalOnMissingBean(CamundaJobConfiguration.class)
@ConditionalOnProperty(prefix = "camunda.bpm.job-execution", name = "enabled", havingValue = "true", matchIfMissing = true)
public static CamundaJobConfiguration camundaJobConfiguration() {
return new DefaultJobConfiguration();
}
@Bean
@ConditionalOnMissingBean(CamundaHistoryConfiguration.class)
public static CamundaHistoryConfiguration camundaHistoryConfiguration() {
return new DefaultHistoryConfiguration();
}
@Bean
@ConditionalOnMissingBean(CamundaMetricsConfiguration.class)
public static CamundaMetricsConfiguration camundaMetricsConfiguration() {
return new DefaultMetricsConfiguration();
}
//TODO to be removed within CAM-8108
@Bean(name = "historyLevelAutoConfiguration")
@ConditionalOnMissingBean(CamundaHistoryLevelAutoHandlingConfiguration.class)
@ConditionalOnProperty(prefix = "camunda.bpm", name = "history-level", havingValue = "auto", matchIfMissing = false)
@Conditional(NeedsHistoryAutoConfigurationCondition.class)
public static CamundaHistoryLevelAutoHandlingConfiguration historyLevelAutoHandlingConfiguration() {
return new DefaultHistoryLevelAutoHandlingConfiguration();
}
//TODO to be removed within CAM-8108
@Bean(name = "historyLevelDeterminator")
@ConditionalOnMissingBean(name = { "camundaBpmJdbcTemplate", "historyLevelDeterminator" })
@ConditionalOnBean(name = "historyLevelAutoConfiguration")
public static HistoryLevelDeterminator historyLevelDeterminator(CamundaBpmProperties camundaBpmProperties, JdbcTemplate jdbcTemplate) {
return createHistoryLevelDeterminator(camundaBpmProperties, jdbcTemplate);
}
//TODO to be removed within CAM-8108
@Bean(name = "historyLevelDeterminator")
@ConditionalOnBean(name = { "camundaBpmJdbcTemplate", "historyLevelAutoConfiguration", "historyLevelDeterminator" })
@ConditionalOnMissingBean(name = "historyLevelDeterminator")
public static HistoryLevelDeterminator historyLevelDeterminatorMultiDatabase(CamundaBpmProperties camundaBpmProperties,
@Qualifier("camundaBpmJdbcTemplate") JdbcTemplate jdbcTemplate) {
return createHistoryLevelDeterminator(camundaBpmProperties, jdbcTemplate);
}
@Bean
@ConditionalOnMissingBean(CamundaAuthorizationConfiguration.class)
public static CamundaAuthorizationConfiguration camundaAuthorizationConfiguration() {
return new DefaultAuthorizationConfiguration();
}
@Bean
@ConditionalOnMissingBean(CamundaDeploymentConfiguration.class)
public static CamundaDeploymentConfiguration camundaDeploymentConfiguration() {
return new DefaultDeploymentConfiguration();
}
// ********************************************************************************************
// 1. GenericPropertiesConfiguration实际为:ProcessEnginePlugin接口的实现
// ********************************************************************************************
@Bean
public GenericPropertiesConfiguration genericPropertiesConfiguration() {
return new GenericPropertiesConfiguration();
}
@Bean
@ConditionalOnProperty(prefix = "camunda.bpm.admin-user", name = "id")
public CreateAdminUserConfiguration createAdminUserConfiguration() {
return new CreateAdminUserConfiguration();
}
@Bean
@ConditionalOnMissingBean(CamundaFailedJobConfiguration.class)
public static CamundaFailedJobConfiguration failedJobConfiguration() {
return new DefaultFailedJobConfiguration();
}
@Bean
@ConditionalOnProperty(prefix = "camunda.bpm.filter", name = "create")
public CreateFilterConfiguration createFilterConfiguration() {
return new CreateFilterConfiguration();
}
@Bean
public EventPublisherPlugin eventPublisherPlugin(CamundaBpmProperties properties, ApplicationEventPublisher publisher) {
return new EventPublisherPlugin(properties.getEventing(), publisher);
}
@Bean
public CamundaIntegrationDeterminator camundaIntegrationDeterminator() {
return new CamundaIntegrationDeterminator();
}
}
(3). GenericPropertiesConfiguration
@Order(Ordering.DEFAULT_ORDER - 1)
public class GenericPropertiesConfiguration
// *****************************************************************************
// AbstractCamundaConfiguration实际是:SpringProcessEnginePlugin接口的实现类
// *****************************************************************************
extends AbstractCamundaConfiguration {
protected static final SpringBootProcessEngineLogger LOG = SpringBootProcessEngineLogger.LOG;
@Override
public void preInit(SpringProcessEngineConfiguration springProcessEngineConfiguration) {
// GenericProperties就是一个Map
GenericProperties genericProperties = camundaBpmProperties.getGenericProperties();
final Map<String, Object> properties = genericProperties.getProperties();
if (!CollectionUtils.isEmpty(properties)) {
SpringBootStarterPropertyHelper
.applyProperties(springProcessEngineConfiguration, properties, genericProperties.isIgnoreUnknownFields());
LOG.propertiesApplied(genericProperties);
}
} // end preInit
}
(4). SpringBootStarterPropertyHelper
public class SpringBootStarterPropertyHelper {
protected static final SpringBootProcessEngineLogger LOG = SpringBootProcessEngineLogger.LOG;
// ***********************************************************************************************
// T: SpringProcessEngineConfiguration
// 把sourceMap的信息应用到:SpringProcessEngineConfiguration实例上
// ***********************************************************************************************
public static <T> void applyProperties(T target, Map<String, Object> sourceMap, boolean ignoreUnknownFields) {
ConfigurationPropertySource source = new MapConfigurationPropertySource(sourceMap);
Binder binder = new Binder(source);
try {
if (ignoreUnknownFields) {
binder.bind(ConfigurationPropertyName.EMPTY, Bindable.ofInstance(target));
} else {
binder.bind(ConfigurationPropertyName.EMPTY, Bindable.ofInstance(target), new NoUnboundElementsBindHandler(BindHandler.DEFAULT));
}
} catch (Exception e) {
throw LOG.exceptionDuringBinding(e.getMessage());
}
} // end applyProperties
}
(5). ProcessEnginePlugin实现类
org.camunda.bpm.spring.boot.starter.configuration.impl.GenericPropertiesConfiguration
org.camunda.bpm.spring.boot.starter.configuration.impl.DefaultProcessEngineConfiguration
org.camunda.bpm.spring.boot.starter.configuration.impl.DefaultDatasourceConfiguration
org.camunda.bpm.spring.boot.starter.configuration.impl.DefaultJobConfiguration
org.camunda.bpm.spring.boot.starter.configuration.impl.DefaultHistoryConfiguration
org.camunda.bpm.spring.boot.starter.configuration.impl.DefaultMetricsConfiguration
org.camunda.bpm.spring.boot.starter.configuration.impl.DefaultAuthorizationConfiguration
org.camunda.bpm.spring.boot.starter.configuration.impl.DefaultDeploymentConfiguration
org.camunda.bpm.spring.boot.starter.configuration.impl.custom.CreateAdminUserConfiguration
org.camunda.bpm.spring.boot.starter.configuration.impl.DefaultFailedJobConfiguration
org.camunda.bpm.spring.boot.starter.event.EventPublisherPlugin
org.camunda.bpm.spring.boot.starter.plugin.ApplicationContextClassloaderSwitchPlugin
org.camunda.bpm.spring.boot.starter.spin.SpringBootSpinProcessEnginePlugin
(6). 总结
CamundaBpmConfiguration类配置的Bean大多数是:ProcessEnginePlugin接口的实现类,通过随机对ProcessEnginePlugin的实现类进行剖析,内部的原理为:
- 创建:ProcessEngineConfigurationImpl对象的实现类(SpringProcessEngineConfiguration),并把该类交给Spring进行托管.
- 在初始化ProcessEngine时,调用:ProcessEnginePlugin的方法,对:ProcessEngineConfigurationImpl进行配置.
- 一句话理解就是:ProcessEnginePlugin就是对:ProcessEngineConfigurationImpl进行配置化.