Activiti快速入门(二)—— 一行代码启动Activiti引擎

下列示例将演示如何使用一行代码启动Activiti流程引擎,之前的介绍中说到了Activit的核心功能是由7大Service完成的,而7大Service可以从ProcessEngine中获得,所以我们只需要获得ProcessEngine这个对象,便拥有了Activiti所有的功能。
参考源码: GitHub示例

首先做点准备工作:构建一个Maven项目引入Activiti的依赖(5.22和6.0在这儿没有区别)
pom.xml如下

<dependency>
      <groupId>com.h2database</groupId>
       <artifactId>h2</artifactId>
       <version>1.3.176</version>
      <scope>test</scope>
</dependency>
<!--activiti依赖-->
<dependency>
      <groupId>org.activiti</groupId>
      <artifactId>activiti-engine</artifactId>
      <version>6.0.0</version>
</dependency>

接着新建一个测试类 获取流程引擎ProcessEngine 而且从引擎中获取ManagementService这个接口读取我们当前引擎的系统属性。

    @Test
    public void oneLineStartActiviti(){
        ProcessEngine processEngine = ProcessEngineConfiguration.createStandaloneInMemProcessEngineConfiguration()
                .setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_CREATE_DROP)
                .setJdbcUrl("jdbc:h2:mem:my-own-db;DB_CLOSE_DELAY=1000")
                .buildProcessEngine();
        ManagementService managementService = processEngine.getManagementService();
        Map<String, String> properties = managementService.getProperties();
        for (String s : properties.keySet()) {
            System.out.println(s+":"+properties.get(s));
        }
    }

控制台输出如下:

cfg.execution-related-entities-count:false  先忽略此属性
next.dbid:1   下一个主键ID
schema.version:6.0.0.4  当前数据库版本
schema.history:create(5.22.0.0) upgrade(5.22.0.0->6.0.0.4) 数据库升级历史

不过上述项目是通过内存数据库建立的测试引擎,那么我们如何在本地的数据库中建立我们的流程引擎呢,下面我将以Mysql为例(主流数据库都是支持的,不用改配置文件,自动识别)

在本地数据库中启动流程引擎,且创建数据库表

  • 引入mysql驱动依赖
   <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.40</version>
   </dependency>
  • 新建Activiti的配置文件
    这里配置的核心是processEngineConfiguration这个Bean,因为通过这个bean的buildProcessEngine()方法我们可以构建我们的流程引擎对象。
<?xml version="1.0" encoding="UTF-8"?>
<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="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
        <property name="jdbcUrl" value="jdbc:mysql://127.0.0.1:3306/activiti5demo" />
        <property name="jdbcDriver" value="com.mysql.jdbc.Driver" />
        <property name="jdbcUsername" value="root" />
        <property name="jdbcPassword" value="123456" />
        <!--流程引擎名称(使用ProcessEngines.getDefaultProcessEngine()方法时请不要配置流程引擎名称)
        <property name="processEngineName" value="MyProcessEngine"/>
        -->
        <!--
        databaseSchemaUpdate: 设置流程引擎启动和关闭时如何处理数据库表。
        false(默认):检查数据库表的版本和依赖库的版本, 如果版本不匹配就抛出异常。
        true: 构建流程引擎时,执行检查,如果需要就执行更新。 如果表不存在,就创建
        create-drop: 构建流程引擎时创建数据库表, 关闭流程引擎时删除这些表。
        -->
        <property name="databaseSchemaUpdate" value="true"/>
    </bean>
</beans>
  • 使用Activiti配置类读取配置文件初始化流程引擎
    @Test
    public void testDefaltEngine(){
        ProcessEngineConfiguration processEngineConfiguration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml");
        ProcessEngine processEngine = processEngineConfiguration.buildProcessEngine();
        Assert.assertEquals("MyProcessEngine", processEngine.getName());
        RuntimeService runtimeService = processEngine.getRuntimeService();
        Assert.assertNotNull(runtimeService);
        TaskService taskService = processEngine.getTaskService();
        Assert.assertNotNull(taskService);
    }
  • 最简单的获取方式是ProcessEngines.getDefaultProcessEngine()方法,它会自动去ClassPath查找activiti.cfg.xml文件,并按照配置文件创建流程引擎(如果你是按照我的配置来的,这里会报错)
    @Test
    public void getDefaultProcessEngine(){
        ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
        Assert.assertNotNull(engine);
    }

大家有没有发现Activiti的配置文件其实就是一个Spring的配置文件
所以这里我们可以不通过ProcessEngineConfiguration去读取配置文件来创建引擎,我们可以让Spring去实例化这个类(真正和Spring整合的时候需要更改一下配置文件中配置的Bean对象,后期会有专门的文章来讲解如何与Spring整合)

  • 使用Spring容器实例化流程引擎
    引入Activiti-Spring依赖
        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-spring</artifactId>
            <version>6.0.0</version>
        </dependency>
    @Test
    public void testEngine() {
        ApplicationContext context = new ClassPathXmlApplicationContext(new String[] { "activiti.cfg.xml" });
        ProcessEngineConfiguration processEngineConfiguration = (ProcessEngineConfiguration) context.getBean("processEngineConfiguration");
        ProcessEngine processEngine = processEngineConfiguration.buildProcessEngine();
        Assert.assertEquals("MyProcessEngine", processEngine.getName());
        RuntimeService runtimeService = processEngine.getRuntimeService();
        Assert.assertNotNull(runtimeService);
        TaskService taskService = processEngine.getTaskService();
        Assert.assertNotNull(taskService);
    }

这里有个很有意思的坑,我测试了几遍都是获取不到ProcessEngine,同时教大家一个小技巧,因为我们配置的数据库策略databaseSchemaUpdate为 true 所以在引擎启动的时候一定会创建数据库表,所以在刚才的单元测试中我根据数据库判断流程引擎一定是启动的,点进源码可以看到getDefaultProcessEngine()是会将类路径下的所有配置文件都创建一次流程引擎,最后将这些引擎存入Map中Key为引擎名称,value为引擎对象。而getDefaultProcessEngine()只会从这个map中查找名为default的对象

 public static final String NAME_DEFAULT = "default";
 protected static Map<String, ProcessEngine> processEngines = new HashMap<String, ProcessEngine>();
 /** Initializes all process engines that can be found on the classpath for 
   * resources <code>activiti.cfg.xml</code> (plain Activiti style configuration)
   * and for resources <code>activiti-context.xml</code> (Spring style configuration). */
  public synchronized static void init() {
    if (!isInitialized()) {
      if(processEngines == null) {
        // Create new map to store process-engines if current map is 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);
      }
      
      // Remove duplicated configuration URL's using set. Some classloaders may return identical URL's twice, causing duplicate startups
      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());
        initProcessEnginFromResource(resource);
      } 略...

所以这里我们只需要将配置文件中的流程名称配置删除就能正常获取流程引擎了

使用Activiti配置类读取配置文件方式还有以下几种,不过原理都是差不多的,了解即可

//使用IO流读取配置
InputStream stream = this.getClass().getClassLoader().getResourceAsStream("activiti.cfg.xml");
ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createProcessEngineConfigurationFromInputStream(stream);
//默认配置
configuration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResourceDefault();
//指定文件名
configuration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml");
      

还可以借助Activiti给我们提供的单元测试类ActivitiRule来获取引擎以及7大Service

    @Rule
    public ActivitiRule activitiRule  =  new ActivitiRule();
    @Test
    public void activitiUnitTest(){
        ProcessEngine engine = activitiRule.getProcessEngine();
        System.out.println(engine.getName());
        Map<String, String> properties = engine.getManagementService().getProperties();
        for (String s : properties.keySet()) {
            System.out.println(s+":"+properties.get(s));
        }
    }

通过流程引擎获取7大Service接口,后续我会讲解如何使用这7大Service来真正的使用Activiti

@Test
    public void setActivitiRule(){
        ProcessEngine engine = activitiRule.getProcessEngine();
        //这里不局限于使用activitiRule类获取的引擎,前面所有的方式获取的流程引擎都可以按照如下方式使用
        IdentityService identityService = engine.getIdentityService();
        RepositoryService repositoryService = engine.getRepositoryService();
        RuntimeService runtimeService = engine.getRuntimeService();
        TaskService taskService = engine.getTaskService();
        FormService formService = engine.getFormService();
        ManagementService managementService = engine.getManagementService();
        HistoryService historyService = engine.getHistoryService();
    }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容