This is the 11th day of my participation in Gwen Challenge
>>>> 😜😜😜 Making: 👉 github.com/black-ant
A. The preface
👉 Activiti 7 is basic to use, this article will take a look at activiti configuration
2. Configure the main process
The first thing to know is where the configuration is initiated:
2.1 Starting Point of Configuration
After integration Activiti – Spring, is through the ProcessEngineAutoConfiguration configuration:
@Configuration
@AutoConfigureAfter(DataSourceAutoConfiguration.class)
@EnableConfigurationProperties(ActivitiProperties.class)
public class ProcessEngineAutoConfiguration extends AbstractProcessEngineAutoConfiguration {
private final UserGroupManager userGroupManager;
public ProcessEngineAutoConfiguration(UserGroupManager userGroupManager) {
this.userGroupManager = userGroupManager;
}
@Bean
@ConditionalOnMissingBean
public SpringProcessEngineConfiguration springProcessEngineConfiguration(
DataSource dataSource,
PlatformTransactionManager transactionManager,
SpringAsyncExecutor springAsyncExecutor,
ActivitiProperties activitiProperties,
ProcessDefinitionResourceFinder processDefinitionResourceFinder,
@Autowired(required = false) ProcessEngineConfigurationConfigurer processEngineConfigurationConfigurer) throws IOException {
/ / 2.2 configuration SpringProcessEngineConfiguration
SpringProcessEngineConfiguration conf = new SpringProcessEngineConfiguration();
configureProcessDefinitionResources(processDefinitionResourceFinder,conf);
// Set the DataSource and transaction manager
conf.setDataSource(dataSource);
conf.setTransactionManager(transactionManager);
if(springAsyncExecutor ! =null) {
// SpringAsyncExecutor -> PS:21001
conf.setAsyncExecutor(springAsyncExecutor);
}
conf.setDeploymentName(activitiProperties.getDeploymentName());
// Database update type -> PS:21002
conf.setDatabaseSchema(activitiProperties.getDatabaseSchema());
conf.setDatabaseSchemaUpdate(activitiProperties.getDatabaseSchemaUpdate());
conf.setDbHistoryUsed(activitiProperties.isDbHistoryUsed());
conf.setAsyncExecutorActivate(activitiProperties.isAsyncExecutorActivate());
// Configure the email system information
conf.setMailServerHost(activitiProperties.getMailServerHost());
conf.setMailServerPort(activitiProperties.getMailServerPort());
conf.setMailServerUsername(activitiProperties.getMailServerUserName());
conf.setMailServerPassword(activitiProperties.getMailServerPassword());
conf.setMailServerDefaultFrom(activitiProperties.getMailServerDefaultFrom());
conf.setMailServerUseSSL(activitiProperties.isMailServerUseSsl());
conf.setMailServerUseTLS(activitiProperties.isMailServerUseTls());
// User group manager
if(userGroupManager ! =null) {
conf.setUserGroupManager(userGroupManager);
}
conf.setHistoryLevel(activitiProperties.getHistoryLevel());
// Customize Mybatis Mapper
if(activitiProperties.getCustomMybatisMappers() ! =null) {
conf.setCustomMybatisMappers(getCustomMybatisMapperClasses(activitiProperties.getCustomMybatisMappers()));
}
if(activitiProperties.getCustomMybatisXMLMappers() ! =null) {
conf.setCustomMybatisXMLMappers(new HashSet<>(activitiProperties.getCustomMybatisXMLMappers()));
}
if(activitiProperties.getCustomMybatisXMLMappers() ! =null) {
conf.setCustomMybatisXMLMappers(new HashSet<>(activitiProperties.getCustomMybatisXMLMappers()));
}
// ID generator: an implementation based on the current time and the Ethernet address of the machine running it
if (activitiProperties.isUseStrongUuids()) {
conf.setIdGenerator(new StrongUuidGenerator());
}
conf.setActivityBehaviorFactory(new CloudActivityBehaviorFactory());
if(processEngineConfigurationConfigurer ! =null) {
/ / set configuration for processEngineConfigurationConfigurer
processEngineConfigurationConfigurer.configure(conf);
}
return conf;
}
private void configureProcessDefinitionResources(ProcessDefinitionResourceFinder processDefinitionResourceFinder, SpringProcessEngineConfiguration conf) throws IOException {
List<Resource> procDefResources = processDefinitionResourceFinder.discoverProcessDefinitionResources();
if(! procDefResources.isEmpty()) { conf.setDeploymentResources(procDefResources.toArray(new Resource[0])); }}@Bean
@ConditionalOnMissingBean
public ProcessDefinitionResourceFinder processDefinitionResourceFinder(ActivitiProperties activitiProperties, ResourcePatternResolver resourcePatternResolver) {
return newProcessDefinitionResourceFinder(activitiProperties, resourcePatternResolver); }}Copy the code
PS:21002 SpringAsyncExecutor function
What it does: This is a Spring-based implementation of the Job Executor that uses the Spring abstract TaskExecutor to perform background tasks
C- SpringAsyncExecutor
// Perform a simple task executor interface processor
protected TaskExecutor taskExecutor;
// A policy for processing jobs that have been acquired but cannot be executed at this time (exceeding the queue size)
protected SpringRejectedJobsHandler rejectedJobsHandler;
Copy the code
Take a look at TaskExecutor’s system 👉
PS:21002 databaseSchemaUpdate Specifies the value of the attribute
DatabaseSchemaUpdate property values:
Flase: default value. When creating the process engine, check the version of the DB schema against the library and throw an exception true if the version does not match: After building the process engine, a check is performed and the schema is updated if necessary: The schema is created when the process engine is created and deleted when the process engine is shut down (you must manually shut down the engine to delete the tables). Drop-create: Drop the original old table when Activiti starts and then create a new table (no need to manually shut down the engine).
There are several concerns:
@AutoConfigureAfter(DataSourceAutoConfiguration.class)
@EnableConfigurationProperties(ActivitiProperties.class)
Copy the code
The role of DataSourceAutoConfiguration:
This file is org. Springframework. Boot. Autoconfigure. JDBC of files, because there are data manipulation activiti, so you need to use a DataSource, here is the use of the unity of the Spring
What is ActivitiProperties?
@ConfigurationProperties("spring.activiti")
public class ActivitiProperties {
private boolean checkProcessDefinitions = true;
private boolean asyncExecutorActivate = false;
private String deploymentName = "SpringAutoDeployment";
private String mailServerHost = "localhost";
private int mailServerPort = 1025;
private String mailServerUserName;
private String mailServerPassword;
private String mailServerDefaultFrom;
private boolean mailServerUseSsl;
private boolean mailServerUseTls;
private String databaseSchemaUpdate = "true";
private String databaseSchema;
private boolean isDbHistoryUsed = false;
// Historical level
private HistoryLevel historyLevel = HistoryLevel.NONE;
// Default process document
private String processDefinitionLocationPrefix = "classpath:/processes/";
// Process configuration file suffix
private List<String> processDefinitionLocationSuffixes = Arrays.asList("**.bpmn20.xml"."**.bpmn");
// Allow custom DAO operations
private List<String> customMybatisMappers;
private List<String> customMybatisXMLMappers;
private boolean useStrongUuids = true;
}
// As you can see here, there are many configurations available in Activiti, which can be configured as required:
HistoryLevel (none /activity / audit/full )
Copy the code
2.3 Configuration Initialization
In ProcessEngineAutoConfiguration above, you can see through the new SpringProcessEngineConfiguration (); Build the object, in fact, in addition to ProcessEngineAutoConfiguration, there are many other objects, we each take a look at:
The main configuration classes for Spring Activiti 7 include the following:C- SpringProcessEngineConfiguration C- JtaProcessEngineConfiguration C- MultiSchemaMultiTenantProcessEngineConfiguration C- StandaloneInMemProcessEngineConfiguration C- StandaloneProcessEngineConfigurationCopy the code
Let’s see what they did:
2.3.1 SpringProcessEngineConfiguration
C - SpringProcessEngineConfiguration E - ProcessEngineConfigurationImpl it2A class is very huge, we just look at some of the important parts: C - SpringProcessEngineConfiguration MC - SpringProcessEngineConfiguration: Where the AutoDeploymentStrategy collection -> PS is configured:35001M -buildProcessEngine: buildProcessEngine M -getUserGroupManager: UserGroupManager -> PS:35002M - setTransactionSynchronizationAdapterOrder M - initDefaultCommandConfig: initialize the default configuration - > PS:35003M - createTransactionInterceptor: return SpringTransactionInterceptor M - initTransactionContextFactory:newA SpringTransactionContextFactory - > PS:35004M-initjpa: builds JPA m-AutoDeployResources M-setdatasource: sets the data source to be used where additional dependencies need to be generated or used@Bean -> PS:35005
Copy the code
PS: 35001 AutoDeploymentStrategy role
Function: Policy interface for automatic resource deployment. A policy can perform any number of deployments for the resources it provides.
Policies can handle deployments corresponding to specific specified deployment patterns. This applicability can be verified using the #handlesMode(String) method
AutoDeploymentStrategy is an interface: Deploy
C- AutoDeploymentStrategy
M- boolean handlesMode(final String mode)? - Determines whether the policy handles the deployment M- of the provided deployment modevoid deployResources(final String deploymentNameHint, final Resource[] resources, final RepositoryService repositoryService)? - Deploy the provided resource, using the provided name as a prompt, and using the provided RepositoryService to perform the deploymentCopy the code
He has three implementation classes:
- C – DefaultAutoDeploymentStrategy: will all resources combined into a single deployment
- C – ResourceParentFolderAutoDeploymentStrategy: in order to share the same parent folder of each resource set for the deployment of alone
- C – SingleResourceAutoDeploymentStrategy: by name to perform separate each resource deployment
Activiti – AutoDeploymentStrategy 👉
PS:35002 UserGroupManager
- List<String> getUserGroups(String username);
- List<String> getUserRoles(String username);
- List<String> getGroups(a);
- List<String> getUsers(a); C - ActivitiUserGroupManagerImpl: main implementation class F - UserDetailsService UserDetailsService// Run the userDetailsService command to obtain the related status
@Override
public List<String> getUserGroups(String username) {
return userDetailsService.loadUserByUsername(username).getAuthorities().stream()
.filter((GrantedAuthority a) -> a.getAuthority().startsWith("GROUP_"))
.map((GrantedAuthority a) -> a.getAuthority().substring(6))
.collect(Collectors.toList());
}
@Override
public List<String> getUserRoles(String username) {
return userDetailsService.loadUserByUsername(username).getAuthorities().stream()
.filter((GrantedAuthority a) -> a.getAuthority().startsWith("ROLE_"))
.map((GrantedAuthority a) -> a.getAuthority().substring(5))
.collect(Collectors.toList());
}
Copy the code
PS:35003 SpringTransactionInterceptor
C- SpringTransactionInterceptor
E- AbstractCommandInterceptor
Copy the code
PS:35004 SpringTransactionContextFactory
public class SpringTransactionContextFactory implements TransactionContextFactory {
// This is the central interface in Spring's transaction infrastructure
protected PlatformTransactionManager transactionManager;
protected Integer transactionSynchronizationAdapterOrder;
/ /...
}
Copy the code
PS: 35005 build TransactionAwareDataSourceProxy
public ProcessEngineConfiguration setDataSource(DataSource dataSource) {
if (dataSource instanceof TransactionAwareDataSourceProxy) {
return super.setDataSource(dataSource);
} else {
// Wrap datasource in Transaction-aware proxy
DataSource proxiedDataSource = new TransactionAwareDataSourceProxy(dataSource);
return super.setDataSource(proxiedDataSource); }}Copy the code
The role of TransactionAwareDataSourceProxy
C – TransactionAwareDataSourceProxy – target JDBC javax.mail. SQL agent. The data source, Add spring management awareness, TransactionAwareDataSourceProxy is the outermost layers of the data source proxy/adapter chain data sources, TransactionAwareDataSourceProxy can directly entrusted to the target connection pool or some intermediary agent/adapter
Simply put: Data access code that does not have Spring data access support can seamlessly participate in Spring-managed transactions with this broker
Activiti – ProcessEngineConfigurationImpl 👉
2.3.2 JtaProcessEngineConfiguration role
What it does: Uses JTA for transaction management without Activiti transactions
The Java Transaction API, commonly known as JTA, is an API for managing transactions in Java, simply javax.Transaction; The architecture of
public class JtaProcessEngineConfiguration extends ProcessEngineConfigurationImpl {
protected TransactionManager transactionManager;
public CommandInterceptor createTransactionInterceptor(a) {
/ / as you can see, constructed a JtaTransactionInterceptor here
return new JtaTransactionInterceptor(transactionManager);
}
public void initTransactionContextFactory(a) {
if (transactionContextFactory == null) {
/ / build a JtaTransactionContextFactory factory class
transactionContextFactory = newJtaTransactionContextFactory(transactionManager); }}}Copy the code
2.3.3 MultiSchemaMultiTenantProcessEngineConfiguration
Role: a multi-tenant environment, building multi-tenant ProcessEngine ProcessEngineConfiguration, in which each tenant has its own database schema
// The dataSource is bound to tenantId
public void registerTenant(String tenantId, DataSource dataSource) {
((TenantAwareDataSource) super.getDataSource()).addDataSource(tenantId, dataSource);
if (booted) {
createTenantSchema(tenantId);
createTenantAsyncJobExecutor(tenantId);
tenantInfoHolder.setCurrentTenantId(tenantId);
super.postProcessEngineInitialisation(); tenantInfoHolder.clearCurrentTenantId(); }}public ProcessEngine buildProcessEngine(a) {
Disable schema creation/validation by setting it to NULL
String originalDatabaseSchemaUpdate = this.databaseSchemaUpdate;
this.databaseSchemaUpdate = null;
boolean originalIsAutoActivateAsyncExecutor = this.asyncExecutorActivate;
this.asyncExecutorActivate = false;
ProcessEngine processEngine = super.buildProcessEngine();
// Reset to the original value
this.databaseSchemaUpdate = originalDatabaseSchemaUpdate;
this.asyncExecutorActivate = originalIsAutoActivateAsyncExecutor;
// Create tenant mode
for (String tenantId : tenantInfoHolder.getAllTenants()) {
createTenantSchema(tenantId);
}
// Start executing the program asynchronously
if(asyncExecutor ! =null && originalIsAutoActivateAsyncExecutor) {
asyncExecutor.start();
}
booted = true;
return processEngine;
}
Copy the code
2.3.4 StandaloneInMemProcessEngineConfiguration
// Use the in-memory database, where H2 is used
public StandaloneInMemProcessEngineConfiguration(a) {
this.databaseSchemaUpdate = DB_SCHEMA_UPDATE_CREATE_DROP;
this.jdbcUrl = "jdbc:h2:mem:activiti";
}
Copy the code
In a nutshell, this configuration configures the use of an in-memory database
conclusion
Activiti 7 configuration is almost complete. Next, take a look at its database operations.
The appendix
🇨 🇳 ⚽ ✊ 🏆 🎉