activiti學習筆記(二) 獲取流程例項
阿新 • • 發佈:2022-05-03
獲取流程例項
流程例項獲取的原始碼解析
以獲取預設的流程例項為例,來解釋整個流程例項的獲取過程
檔案位置:/org/activiti/engine/ProcessEngines.java
第一步:通過getDefaultProcessEngine來獲取,可以看出其呼叫的當前類的getProcessEngine方法。
//獲取預設的流程引擎例項 NAME_DEFAULT="default" public static ProcessEngine getDefaultProcessEngine() { return getProcessEngine(NAME_DEFAULT); }
第二步: 根據ProcessEngine的name獲取指定的ProcessEngine
/** * @author 鄭小康 * 根據ProcessEngine的name獲取指定的ProcessEngine * */ public static ProcessEngine getProcessEngine(String processEngineName) { if (!isInitialized()) { init(); } return processEngines.get(processEngineName); }
第三步:呼叫init方法,來對流程引擎進行初始化
/** * @author 鄭小康 * * 該方法使用了synchronized 再次檢測其是否被初始化,避免其它客戶端進行了初始化 * * 1.檢驗是否初始化,預設值為false,第一次進來肯定是false,然後向下進行執行 * * 2.檢驗processEngines是否存在,如果不存在則構建一個HashMap例項 * * 3.獲取當前類載入器,根據類載入器獲取activiti.cfg.xml資原始檔,如果不存在則扔出異常,要求必須命名為activiti.cfg.xml * * 4.遍歷所有的資原始檔,通過initProcessEngineFromSpringResource這個方法構建其processEngine例項並新增其對應的屬性 * * 5.將初始化屬性isInitialized的值設為true * */ public synchronized static void init() { if (!isInitialized()) { if (processEngines == null) { processEngines = new HashMap<String, ProcessEngine>(); } ClassLoader classLoader = ReflectUtil.getClassLoader(); Enumeration<URL> resources = null; try { resources = classLoader.getResources("activiti.cfg.xml"); } catch (IOException e) { throw new ActivitiIllegalArgumentException("problem retrieving activiti.cfg.xml resources on the classpath: " + System.getProperty("java.class.path"), e); } Set<URL> configUrls = new HashSet<URL>(); while (resources.hasMoreElements()) { configUrls.add(resources.nextElement()); } for (Iterator<URL> iterator = configUrls.iterator(); iterator.hasNext();) { URL resource = iterator.next(); log.info("Initializing process engine using configuration '{}'", resource.toString()); initProcessEngineFromResource(resource); } try { resources = classLoader.getResources("activiti-context.xml"); } catch (IOException e) { throw new ActivitiIllegalArgumentException("problem retrieving activiti-context.xml resources on the classpath: " + System.getProperty("java.class.path"), e); } while (resources.hasMoreElements()) { URL resource = resources.nextElement(); log.info("Initializing process engine using Spring configuration '{}'", resource.toString()); initProcessEngineFromSpringResource(resource); } setInitialized(true); } else { log.info("Process engines already initialized"); } }
第四步:通過initProcessEngineFromResource方法來進行ProcessEngine例項以及其一系列相關屬性的建立,核心是呼叫了buildProcessEngine來構建其例項
/**
* @author 鄭小康
*
* 1.從processEngineInfosByResourceUrl中獲取流程配置資訊
*
* 2.如果processEngineInfo不為空,移除所有與ProcessEngine相關的資訊
*
* 3.構建ProcessEngine例項,將其新增到processEngines
*
* 4.構建processEngineInfo例項,將其加入到processEngineInfosByName processEngineInfosByResourceUrl processEngineInfos.add(processEngineInfo);
*
* */
private static ProcessEngineInfo initProcessEngineFromResource(URL resourceUrl) {
ProcessEngineInfo processEngineInfo = processEngineInfosByResourceUrl.get(resourceUrl.toString());
// if there is an existing process engine info
if (processEngineInfo != null) {
// remove that process engine from the member fields
processEngineInfos.remove(processEngineInfo);
if (processEngineInfo.getException() == null) {
String processEngineName = processEngineInfo.getName();
processEngines.remove(processEngineName);
processEngineInfosByName.remove(processEngineName);
}
processEngineInfosByResourceUrl.remove(processEngineInfo.getResourceUrl());
}
String resourceUrlString = resourceUrl.toString();
try {
log.info("initializing process engine for resource {}", resourceUrl);
ProcessEngine processEngine = buildProcessEngine(resourceUrl);
String processEngineName = processEngine.getName();
log.info("initialised process engine {}", processEngineName);
processEngineInfo = new ProcessEngineInfoImpl(processEngineName, resourceUrlString, null);
processEngines.put(processEngineName, processEngine);
processEngineInfosByName.put(processEngineName, processEngineInfo);
} catch (Throwable e) {
log.error("Exception while initializing process engine: {}", e.getMessage(), e);
processEngineInfo = new ProcessEngineInfoImpl(null, resourceUrlString, getExceptionString(e));
}
processEngineInfosByResourceUrl.put(resourceUrlString, processEngineInfo);
processEngineInfos.add(processEngineInfo);
return processEngineInfo;
}
第五步:buildProcessEngine方法來構建例項,先獲取配置例項,在呼叫其的buildProcessEngine方法來例項化,具體實現類是ProcessEngineConfigurationImpl
/**
* @author 鄭小康
* 根據檔案路徑,構建其ProcessEngineConfiguration例項,呼叫buildProcessEngine方法建立ProcessEngine例項
* */
private static ProcessEngine buildProcessEngine(URL resource) {
InputStream inputStream = null;
try {
inputStream = resource.openStream();
ProcessEngineConfiguration processEngineConfiguration = ProcessEngineConfiguration.createProcessEngineConfigurationFromInputStream(inputStream);
return processEngineConfiguration.buildProcessEngine();
} catch (IOException e) {
throw new ActivitiIllegalArgumentException("couldn't open resource stream: " + e.getMessage(), e);
} finally {
IoUtil.closeSilently(inputStream);
}
}
以上就是一個流程例項獲取的過程,其實不難發現,我們不一定要獲取預設的,我們也可以根據指定的processEngineName利用getProcessEngine來獲取對應的流程例項,結合上文我們還能自己構建流程配置例項,直接進行獲取
配置檔案
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName">
<value>com.mysql.jdbc.Driver</value>
</property>
<property name="url">
<value>jdbc:mysql://127.0.0.1:3306/activiti-study?useUnicode=true&characterEncoding=UTF-8
</value>
</property>
<property name="username">
<value>root</value>
</property>
<property name="password" value="fadp" />
</bean>
<bean id="processEngine1"
class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
<property name="dataSource" ref="dataSource" />
<property name="databaseSchemaUpdate" value="true" />
</bean>
</beans>
獲取的方法
@Test
public void getDefaultProcessEngine() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
System.out.println(processEngine);
}
但是這樣就必須按照其要求的檔案目錄結構,我很不喜歡這樣,我想自己定製,所以我實現的方式是,構建流程配置例項再建立流程例項
private final String cfgXml = System.getProperty("user.dir") + "/resource/activiti.cfg.xml";
@Test
public void createProcessEngineConfigurationFromResource() throws IOException {
InputStream in = new FileInputStream(cfgXml);
ProcessEngineConfiguration processEngineConfiguration = ProcessEngineConfiguration.createProcessEngineConfigurationFromInputStream(in,"processEngine1");
System.out.println(processEngineConfiguration);
ProcessEngine processEngine=processEngineConfiguration.buildProcessEngine();
System.out.println(processEngine);
}