activiti5.0.alpha1之流程引擎建立入口

来源:互联网 发布:父与子的编程之旅 编辑:程序博客网 时间:2024/05/21 09:50

从activiti的example开始,example中所有的测试类都继承了ActivitiTestCase,顾名思义,ActivitiTestCase明显是对环节进行初始化的基类,然后看到ActivitiTestCase继承了ProcessEngineTestCase,在ProcessEngineTestCase之中,对引擎进行了初始化。

那么,首先,让我们来看看ProcessEngineTestCase是怎样进行初始化的,籍此追溯到activiti的源码中去。

public class ProcessEngineTestCase extends LogTestCase {

  protected static ProcessEngine processEngine;//流程引擎
  
  protected static ProcessService processService;//流程服务
 
  protected static TaskService taskService;//任务服务
 
  protected static ManagementService managementService;//管理服务
 
  protected static IdentityService identityService;//认证服务
 
  String configurationResource = "activiti.cfg.xml";//默认配置文件

 

  /** allows for tests to configure another configuration resource then the default activiti.cfg.xml.
   * Tests should call this method in the constructor.

   * 允许测试类提供其他配置文件覆盖activiti.cfg.xml,需要在测试类的构造方法中调用此方法

   */
  protected void setConfigurationResource(String configurationResource) {
    this.configurationResource = configurationResource;
  }

 

 

  protected void setUp() throws Exception {
    buildProcessEngine();//初始化流程引擎
    super.setUp();
  }

 

  public void buildProcessEngine() {
    if (processEngine==null) {

      //根据配置文件建立流程引擎
      processEngine = new Configuration()
        .configurationResource(configurationResource)
        .buildProcessEngine()
;

      //从流程引擎中获取各项流程服务
      processService = processEngine.getProcessService();
      taskService = processEngine.getTaskService();
      managementService = processEngine.getManagementService();
      identityService = processEngine.getIdentityService();
    }
  }

  //关闭流程引擎并移除各项流程服务
  public static void closeProcessEngine() {
    if (processEngine!=null) {
      processEngine.close();
      processEngine = null;
      processService = null;
      taskService = null;
      identityService = null;
      managementService = null;
    }
  }
 
  protected void tearDown() throws Exception {
    checkDbIsClean();//察看数据库是否干净
    super.tearDown();
  }
 
  protected void checkDbIsClean() {
    Map<String, Long> tableCounts = processEngine.getManagementService().getTableCount();
    StringBuilder outputMessage = new StringBuilder();
    for (String table : tableCounts.keySet()) {
      Long count = tableCounts.get(table);
      if (!table.equals("ACT_PROPERTY") && count != 0L) {
        outputMessage.append(table + ":" + count + " record(s) ");
      }
    }
   
    if (outputMessage.length() > 0) {
      outputMessage.insert(0, "Database not clean! ");
      throw new ActivitiException(outputMessage.toString());
    }
  }

  //重置流程缓存
  protected void resetProcessCache() {
    ProcessEngineImpl processEngineImpl = (ProcessEngineImpl) processEngine;
    ProcessCache processCache = processEngineImpl.getConfigurationObject(
            Configuration.NAME_PROCESSCACHE, ProcessCache.class);
    processCache.reset();
  }

}

看了源程序之后,很明显,流程引擎的创建就在于buildProcessEngine() 方法中:

processEngine = new Configuration()
        .configurationResource(configurationResource)
        .buildProcessEngine();

单纯看这段代码,是读取配置文件并创建流程引擎,接下来就要看Configuration中是如何建立流程引擎的了。

public class Configuration {
 
  private static Logger log = Logger.getLogger(Configuration.class.getName());
 
  public static final String NAME_COMMANDEXECUTOR = "CommandExecutor";
  public static final String NAME_DBSCHEMA = "DbSchema";
  public static final String NAME_IBATISSQLSESSIONFACTORY = "IbatisSqlSessionFactory";
  public static final String NAME_DBIDGENERATOR = "DbidGenerator";
  public static final String NAME_DEPLOYERMANAGER = "DeployerManager";
  public static final String NAME_PROCESSCACHE = "ProcessCache";
  public static final String NAME_PERSISTENCETYPEISSQL = "PersistenceTypeIsSQL";
  public static final String NAME_TRANSACTIONALOBJECTDESCRIPTORS = "TransactionalObjectDescriptors";
  public static final String NAME_JOBEXECUTOR = "JobExecutor";
 
  protected String name = null;
  protected String type = null;
  protected Map<String, Object> configurations = new HashMap<String, Object>();
 
  public Configuration() {
    log.info("activiti version "+ProcessEngine.VERSION);
  }
 
  public Configuration configurationObject(String name, Object object) {
    configurations.put(name, object);
    return this;
  }

  public Configuration configurationResource(String resourceName) {
    ConfigurationParser.INSTANCE
      .createParse()
      .configuration(this)
      .sourceResource(resourceName)
      .execute();

    return this;
  }
 
  public Configuration configurationUrl(URL url) {
    ConfigurationParser.INSTANCE
      .createParse()
      .configuration(this)
      .sourceUrl(url)
      .execute();
 
    return this;
  }


  public ProcessEngine buildProcessEngine() {
    if (type!=null) {
      return ReflectUtil.instantiate(type, new Object[]{this});
    }
    return new ProcessEngineImpl(this);
  }

  public String getName() {
    return name;
  }
  public void setName(String name) {
    this.name = name;
  }
  public String getType() {
    return type;
  }
  public void setType(String type) {
    this.type = type;
  }
  public Map<String, Object> getConfigurations() {
    return configurations;
  }
  public void setConfigurations(Map<String, Object> configurations) {
    this.configurations = configurations;
  }

}

首先是读取配置文件进行初始化(详情见《activiti5.0之配置文件的结构及功能解析》)

  public Configuration configurationResource(String resourceName) {
    ConfigurationParser.INSTANCE
      .createParse()
      .configuration(this)
      .sourceResource(resourceName)
      .execute();

    return this;
  }

这个方法是将初始化好的本身实例返回,然后再调用的建立流程引擎的方法

  public ProcessEngine buildProcessEngine() {
    if (type!=null) {
      return ReflectUtil.instantiate(type, new Object[]{this});
    }
    return new ProcessEngineImpl(this);
  }

如果type不为null时,则通过反射工具类获取的流程引擎实例(详情见《activiti5.0之强大的反射工具类》);否则,则直接将配置文件注入到流程引擎实现类的构造函数中获取流程引擎实例。

public class ProcessEngineImpl implements ProcessEngine {
 
  private static Logger log = Logger.getLogger(ProcessEngineImpl.class.getName());
 
  protected String name;

  protected Map<String, Object> configurations;
  protected CmdExecutor commandExecutor;
  protected JobExecutor jobExecutor;
 
  protected ProcessServiceImpl processService;
  protected IdentityServiceImpl identityService;
  protected TaskServiceImpl taskService;
  protected ManagementServiceImpl managementService;

  public ProcessEngineImpl(Configuration configuration) {
    this.name = configuration.getName();
    this.configurations = configuration.getConfigurations();
    this.commandExecutor = getConfigurationObject(Configuration.NAME_COMMANDEXECUTOR, CmdExecutor.class);

    this.processService = new ProcessServiceImpl(this);
    this.identityService = new IdentityServiceImpl(this);
    this.taskService = new TaskServiceImpl(this);
    this.managementService = new ManagementServiceImpl(this);
   
    // If we're using a SQL Database, ensure that
    //  the Schema exists and is up-to-date
    // Note - how this is done is likely to change
    //  dramatically in the future with multiple
    //  database types, cloud databases etc
    Boolean isSQL = getConfigurationObject(Configuration.NAME_PERSISTENCETYPEISSQL, Boolean.class);
    if(isSQL) {
      Db.dbSchemaCreate(this);
      Db.dbSchemaCheckVersion(this);
    }
   
    if (name==null) {
      log.info("default activiti ProcessEngine created");
    } else {
      log.info("ProcessEngine "+name+" created");
    }

    // Create and auto-start the Background Job Executor,
    //  if one was requested
    this.jobExecutor = (JobExecutor) getConfigurationObjects().get(Configuration.NAME_JOBEXECUTOR);
    if (jobExecutor!=null) {
      jobExecutor.setProcessEngine(this);
      jobExecutor.start();
    }
  }

  public void close() {
    if (jobExecutor!=null) {
      jobExecutor.shutdownGraceful(true);
    }
   
    Db.dbSchemaDrop(this);
  }

  public Map<String, Object> getConfigurationObjects() {
    return configurations;
  }

  public <T> T getConfigurationObject(String name, Class<?> T) {
    Object configuration = configurations.get(name);
    if (configuration==null) {
      throw new ActivitiException("configuration error: object '"+name+"' is not configured");
    }
    if (!T.isAssignableFrom(configuration.getClass())) {
      throw new ActivitiException("configuration error: object '"+name+"' ("+configuration.getClass().getName()+") is not of type "+T.getName());
    }
    return (T) configurations.get(name);
  }
 
  public <T> T execute(Command<T> command) {
    return commandExecutor.execute(new UserCommandCmd<T>(command), null);
  }

  public TransactionContext openTransactionContext() {
    return new TransactionContext(this);
  }
 
  public TransactionContext createTransactionContext() {
    return new TransactionContext(this);
  }

  public IdentityService getIdentityService() {
    return identityService;
  }
 
  public ManagementService getManagementService() {
    return managementService;
  }

  public TaskService getTaskService() {
    return taskService;
  }

  public CmdExecutor getCmdExecutor() {
    return commandExecutor;
  }
 
  public ProcessService getProcessService() {
    return processService;
  }
 
  public String getName() {
    return name;
  }
  public JobExecutor getJobExecutor() {
    return jobExecutor;
  }
}

从源代码中我们可以看到,流程引擎的初始化分为几大部分:

1.配置信息初始化以备用

    this.name = configuration.getName();
    this.configurations = configuration.getConfigurations();

2.通过配置信息获取命令执行器实例(详情见《activiti5.0之命令模式的极致--命令执行器》)

    this.commandExecutor = getConfigurationObject(Configuration.NAME_COMMANDEXECUTOR, CmdExecutor.class);

3.各项流程服务的初始化

    this.processService = new ProcessServiceImpl(this);
    this.identityService = new IdentityServiceImpl(this);
    this.taskService = new TaskServiceImpl(this);
    this.managementService = new ManagementServiceImpl(this);

4.数据库的初始化

    Boolean isSQL = getConfigurationObject(Configuration.NAME_PERSISTENCETYPEISSQL, Boolean.class);
    if(isSQL) {
      Db.dbSchemaCreate(this);
      Db.dbSchemaCheckVersion(this);
    }

5.任务执行器的初始化和启动(详情见《activiti5.0之核心!任务执行器》)

    this.jobExecutor = (JobExecutor) getConfigurationObjects().get(Configuration.NAME_JOBEXECUTOR);
    if (jobExecutor!=null) {
      jobExecutor.setProcessEngine(this);
      jobExecutor.start();
    }

 

流程引擎的建立过程大致就是如此了,执行详情就在接下来的几篇文章中具体解析。

原创粉丝点击