Activiti6快速入门指南

这个快速入门假定:

  • 熟悉Maven和Java
  • 使用Java的开发环境

本教程将引用以下变量

变量

描述

$mvnProject

maven项目的根位置

$actUnzipedPack

从http://www.activiti.org/download.html下载的解压缩文件的根位置。

$quickStartJavaProjectName

Quick Start Java Project的名称。建议将其作为“ActivitiDeveloperQuickStart”。

...

为简洁起见,请参阅跳过的信息。

$actVer

Activiti的版本目前正在运行。

1.简介

本快速入门显示了使用Activiti将业务流程管理(BPM)嵌入到您的应用程序中的简单性。您将构建一个命令行应用程序,将基于标准的业务流程建模表示法(BPMN)逻辑嵌入到您的应用程序中。

Activiti拥有先进的流程设计工具,可将更复杂的BPM逻辑嵌入到您的应用程序中。这些工具包括基于Eclipse和基于Web的BPMN编辑器,仅举几例。为简洁起见,本快速入门仅使用Activiti的Java API。

有关其他Activiti BPM工具的介绍,请参阅:

  • 样品入门快速入门
  • Activiti用户指南

本快速入门

  • 一般来说,远离特定于IDE的插图(尽管它们是谨慎地完成的)。Activiti适用于任何Java友好的IDE。
  • 使用Maven,但Gradle和Ivy等其他构建和依赖管理系统也可以工作。

2.创建和设置Maven项目

$quickStartJavaProjectName使用以下Maven依赖项创建名为“ActivitiDeveloperQuickStart”(以下称为)的Java项目:

文件:$ mvnProject /pom.xml

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0http://maven.apache.org/xsd/maven-4.0.0.xsd">

<modelVersion>4.0.0</modelVersion>

<groupId>$quickStartJavaProjectName</groupId>

<artifactId>$quickStartJavaProjectName</artifactId>

<version>0.0.1-SNAPSHOT</version>

<!-- ... other configurations mayexist, such as a build stanza, depending your environment ... -->

<dependencies>

<dependency>

<groupId>org.activiti</groupId>

<artifactId>activiti-engine</artifactId>

<version>$actVer</version>

</dependency>

<dependency>

<groupId>org.slf4j</groupId>

<artifactId>slf4j-api</artifactId>

<version>1.7.21</version>

</dependency>

<dependency>

<groupId>org.slf4j</groupId>

<artifactId>slf4j-log4j12</artifactId>

<version>1.7.21</version>

</dependency>

<dependency>

<groupId>com.h2database</groupId>

<artifactId>h2</artifactId>

<version>1.4.193</version>

</dependency>

</dependencies>

</project>

当然,$actVer将替换为下载的Activiti版本。例如,如果您下载的Activiti软件包是“activiti-6.0.0”,那么它的值$actVer将是6.0.0。

请注意以下依赖项:

  • Activiti(org.activiti) - Activiti的BPM引擎
  • 数据库(com.h2database) - H2数据库
  • 记录(org.slf4j) - Java的简单日志外观

在引用构建目录时,本教程假定您的maven项目的标准Maven构建路径:

路径

描述

$mvnProject/ SRC /主/ JAVA

Java源目录

$mvnProject/ src目录/主/资源

资源目录

$mvnProject/ SRC /测试/ JAVA

Java测试目录

$mvnProject/ SRC /测试/资源

资源测试目录

您应该能够构建空白项目。在继续之前,请确保整体状态为“BUILD SUCCESS”。

命令:mvn compile

基本路径:$ mvnProject

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

[INFO] Scanning for projects...

[INFO]

[INFO]------------------------------------------------------------------------

[INFO] Building $quickStartJavaProjectName0.0.1-SNAPSHOT

[INFO]------------------------------------------------------------------------

[INFO]

[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ $quickStartJavaProjectName ---

[WARNING] Using platform encoding(UTF-8 actually) to copyfiltered resources, i.e. build is platform dependent!

[INFO] Copying 0 resource

[INFO]

[INFO] --- maven-compiler-plugin:3.5.1:compile (default-compile) @HelloProcess2 ---

[INFO] Nothing to compile - allclasses are up to date

[INFO]------------------------------------------------------------------------

[INFO] BUILD SUCCESS

[INFO]------------------------------------------------------------------------

[INFO] Total time: 0.592s

[INFO] Finished at: Sun Nov 2705:09:59 EST 2016

[INFO] Final Memory: 10M/309M

[INFO]------------------------------------------------------------------------

 笔记:

  • 您的输出可能看起来不同。最值得注意的是,maven可能需要检索项目依赖项。

3.创建流程引擎

正如之前在maven依赖关系摘要中所建议的那样,Activiti利用Simple Logging Facade for Java(slf4j)进行日志记录。在此示例应用程序中,我们将使用log4j日志记录实现。将log4j.properties文件添加到项目中。

文件:$ mvnProject /src / main / resources / log4j.properties

1

2

3

4

5

log4j.rootLogger=DEBUG, ACT

log4j.appender.ACT=org.apache.log4j.ConsoleAppender

log4j.appender.ACT.layout=org.apache.log4j.PatternLayout

log4j.appender.ACT.layout.ConversionPattern=%d{hh:mm:ss,SSS} [%t] %-5p %c %x - %m%n

使用空白main创建一个新的Java类。

文件:$ mvnProject /src / main / java / com / example / OnboardingRequest.java

1

2

3

4

5

6

7

package com.example;

publicclassOnboardingRequest {

publicstaticvoidmain(String[] args) {

}

}

添加到主要入口点是创建Process Engine。添加到OnboardingRequest.java,如下图所示:

添加到主要入口点是创建Process Engine。添加到OnboardingRequest.java,如下图所示:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

package com.example;

importorg.activiti.engine.ProcessEngine;

importorg.activiti.engine.ProcessEngineConfiguration;

importorg.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration;

publicclassOnboardingRequest {

publicstaticvoidmain(String[] args) {

ProcessEngineConfiguration cfg = newStandaloneProcessEngineConfiguration()

.setJdbcUrl("jdbc:h2:mem:activiti;DB_CLOSE_DELAY=1000")

.setJdbcUsername("sa")

.setJdbcPassword("")

.setJdbcDriver("org.h2.Driver")

.setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);

ProcessEngine processEngine = cfg.buildProcessEngine();

String pName = processEngine.getName();

String ver = ProcessEngine.VERSION;

System.out.println("ProcessEngine[" + pName + "]Version: [" + ver + "]");

}

}

文件:$ mvnProject /src / main / java / com / example / OnboardingRequest.java

添加行

说明

3-4

Activiti流程引擎和配置。

5,9

独立环境的配置帮助程序(例如,不使用依赖项管理器)。

9-15

使用基于内存的h2嵌入式数据库创建Process Engine。

16-18

显示Process Engine配置和Activiti版本。

Activiti支持依赖注入

  • Activiti是专为并且可以轻松利用依赖注入而构建的。有关详细信息,请查看Activiti用户指南

Activiti与许多数据库提供商合作

  • “ $actUnzipedPack/ database / create”中的数据库脚本
  • Activiti用户指南(各种开发和管理部分)

支持IDE和平台独立以及此快速入门的简单性,添加“胖罐”配置,如下面第1-28行到pom.xml中所示。

文件:$ mvnProject /pom.xml

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

...

<build>

...

<plugins>

...

<!--Maven Assembly Plugin -->

<plugin>

<groupId>org.apache.maven.plugins</groupId>

<artifactId>maven-assembly-plugin</artifactId>

<version>2.4.1</version>

<configuration>

<!-- get all project dependencies -->

<descriptorRefs>

<descriptorRef>jar-with-dependencies</descriptorRef>

</descriptorRefs>

<!-- MainClass in mainfest make aexecutable jar -->

<archive>

<manifest>

<mainClass>com.example.OnboardingRequest</mainClass>

</manifest>

</archive>

</configuration>

<executions>

<execution>

<id>make-assembly</id>

<!-- bind to the packaging phase -->

<phase>package</phase>

<goals>

<goal>single</goal>

</goals>

</execution>

</executions>

</plugin>

...

</plugins>

...

</build>

...

</project>

通过运行“mvn package”打包代码。

命令:mvn包

基本路径:$ mvnProject

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

[INFO] Scanning for projects...

[INFO]

[INFO]------------------------------------------------------------------------

[INFO] Building $quickStartJavaProjectName0.0.1-SNAPSHOT

[INFO] ------------------------------------------------------------------------

[INFO]

[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ $quickStartJavaProjectName ---

[WARNING] Using platform encoding(UTF-8 actually) to copyfiltered resources, i.e. build is platform dependent!

[INFO] Copying 1 resource

[INFO]

[INFO] --- maven-compiler-plugin:3.5.1:compile (default-compile) @HelloProcess2 ---

[INFO] Nothing to compile - allclasses are up to date

[INFO]

[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources)@ HelloProcess2 ---

[WARNING] Using platform encoding(UTF-8 actually) to copyfiltered resources, i.e. build is platform dependent!

[INFO] Copying 0 resource

[INFO]

[INFO] --- maven-compiler-plugin:3.5.1:testCompile (default-testCompile) @HelloProcess2 ---

[INFO] Nothing to compile - allclasses are up to date

[INFO]

[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ HelloProcess2---

[INFO]

[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ HelloProcess2 ---

[INFO] Building jar: $mvnProject/target/$quickStartJavaProjectName-0.0.1-SNAPSHOT.jar

[INFO] META-INF/maven/$quickStartJavaProjectName/HelloProcess2/pom.xmlalready added, skipping

[INFO] META-INF/maven/$quickStartJavaProjectName/$quickStartJavaProjectName/pom.properties alreadyadded, skipping

[INFO]

[INFO] --- maven-assembly-plugin:2.4.1:single (make-assembly) @ $quickStartJavaProjectName ---

[INFO] Building jar: $mvnProject/target/$quickStartJavaProjectName-0.0.1-SNAPSHOT-jar-with-dependencies.jar

[INFO]------------------------------------------------------------------------

[INFO] BUILD SUCCESS

[INFO]------------------------------------------------------------------------

[INFO] Total time: 3.029s

[INFO] Finished at: Sun Nov 2707:23:43 EST 2016

[INFO] Final Memory: 33M/702M

[INFO]------------------------------------------------------------------------

笔记:

  • 您的输出可能看起来不同。这里的重要输出是“BUILD SUCCESS”上面的行,显示了带有依赖关系的jar的成功:
  • “[INFO]构建jar:$mvnProject/ target / $quickStartJavaProjectName-0.0.1-SNAPSHOT-jar-with-dependencies.jar”

支持IDE和平台独立以及此快速入门的简单性,从命令行运行Java程序,如下图所示。

命令:cd target

命令:java -jar ActivitiDeveloperQuickStart-0.0.1-SNAPSHOT-jar-with-dependencies.jar

-要么-

java -jar $ quickStartJavaProjectName-0.0.1-SNAPSHOT-jar-with-dependencies.jar

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

11:45:32,849 [main] DEBUGorg.activiti.engine.impl.cfg.ProcessEngineConfigurationImpl  - initializing datasource to db:jdbc:h2:mem:activiti;DB_CLOSE_DELAY=1000

11:45:32,856 [main] DEBUGorg.apache.ibatis.logging.LogFactory  -Logging initialized using 'classorg.apache.ibatis.logging.slf4j.Slf4jImpl' adapter.

...

11:45:33,777 [main] DEBUGorg.activiti.engine.impl.db.DbSqlSession  - SQL: create tableACT_PROCDEF_INFO (

ID_ varchar(64) not null,

PROC_DEF_ID_ varchar(64) not null,

REV_ integer,

INFO_JSON_ID_ varchar(64),

primary key (ID_)

)

...

11:45:33,835 [main] DEBUGorg.activiti.engine.impl.db.DbSqlSession  - activiti db schema create for component identitysuccessful

11:45:33,835 [main] DEBUGorg.activiti.engine.impl.db.DbSqlSession  - flush summary: 0 insert, 0 update, 0 delete.

11:45:33,835 [main] DEBUGorg.activiti.engine.impl.db.DbSqlSession  - now executing flush...

11:45:33,835 [main] DEBUGorg.activiti.engine.impl.cfg.standalone.StandaloneMybatisTransactionContext - firing event committing...

11:45:33,835 [main] DEBUGorg.activiti.engine.impl.cfg.standalone.StandaloneMybatisTransactionContext - committing the ibatis sql session...

11:45:33,835 [main] DEBUGorg.activiti.engine.impl.cfg.standalone.StandaloneMybatisTransactionContext - firing event committed...

11:45:33,836 [main] DEBUGorg.apache.ibatis.transaction.jdbc.JdbcTransaction  - Resetting autocommitto true on JDBC Connection[conn0: url=jdbc:h2:mem:activiti user=SA]

11:45:33,836 [main] DEBUGorg.apache.ibatis.transaction.jdbc.JdbcTransaction  - Closing JDBCConnection [conn0: url=jdbc:h2:mem:activiti user=SA]

11:45:33,836 [main] DEBUGorg.apache.ibatis.datasource.pooled.PooledDataSource  - Returnedconnection 667346055 to pool.

11:45:33,836 [main] DEBUGorg.activiti.engine.impl.interceptor.LogInterceptor  - ---SchemaOperationsProcessEngineBuild finished--------------------------------------------------------

11:45:33,836 [main] DEBUGorg.activiti.engine.impl.interceptor.LogInterceptor  -

11:45:33,836 [main] INFO org.activiti.engine.impl.ProcessEngineImpl  - ProcessEngine defaultcreated

ProcessEngine [default] Version: [$actVer]

笔记:

  • 感兴趣的关键输出是打印您的Activiti版本:$actVer 它应该与配置的版本匹配
  • “[INFO]构建jar:$mvnProject / target / $quickStartJavaProjectName-0.0.1-SNAPSHOT-jar-with-dependencies.jar”

或者,当然,您可以在IDE中运行相同的程序。例如,在Eclipse中,选择OnboardingRequest.java文件,然后右键单击“Run As> Java Application”。如果从IDE中运行程序,结果应该相同(通常显示在IDE的控制台视图中)。

您已经在这个简单的Java程序中成功嵌入了Activiti的BPM引擎。

4.部署流程定义

我们现在准备为Activiti Engine添加额外的BPM逻辑。

为此,正如我们的OnboardingRequest Java类的名称所示,我们将使用简单的Onboarding过程。在这个例子中,我们将输入数据。然后,如果经验年数超过3,则将发布个性化入职欢迎消息的任务。在该任务中,用户将手动将数据输入到虚拟后端系统中。如果多年的经验是3年或更短,那么简单地,通用地,自动地将数据与虚拟后端系统集成。

Activiti的Process Engine符合BPMN 2.0标准。在视觉上,上面的过程可以这样建模:

这个例子非常简单。并且,根据要求,可以通过几种不同的方式对其进行建模。虽然它也可以协调简单的流程,但请注意,Activiti可以处理数十个,数百个甚至数千个步骤的非常复杂的流程。

上面的可视化过程模型的基础是BPMN的XML结构。在这种情况下,XML文档是onboarding.bpmn20.xml。这个快速入门不会深入到底层XML BPMN结构的深度,而是专注于针对Activiti API开发的机制以及将Activiti嵌入到您的应用程序中。然而,为了支持下面的逻辑,这里是相关BPMN形状和基础XML中编写的定义逻辑的摘要:

BPMN形状

Onboarding.bpmn20.xml行

注释

8

开始活动

9-15

用户任务收集2个表单属性:“fullName”和“yearsOfExperience”。请注意,第9行的候选组设置为“管理员”。

21-27

用户任务收集1表单属性:“personalWelcomeTime”。请注意,第22行的候选组设置为“管理员”。

31-35

脚本任务表示自动数据输入到虚拟后端。请注意,虽然简单,但有一个简单的脚本可以设置一个过程变量autoWelcomeTime(第34-35行):var dateAsString = new Date().toString(); execution.setVariable("autoWelcomeTime", dateAsString);

18

定义“经验岁月”专属网关。(决定将产生一条或另一条路径。)

37-39

使用yearsOfExperience变量表示“> 3”逻辑:${yearsOfExperience > 3}

18,36

在专用网关(第18行)上,注意指向“automatedIntroPath(第36行)”的默认节,表示条件“> 3”的逻辑“else”。

298

结束事件

文件:$ mvnProject / src/ main / java / com / example / OnboardingRequest.java

添加行

说明

25-27

加载提供的BPMN模型并将其部署到Activiti Process Engine。

28-33

检索已部署的模型,证明它位于Activiti存储库中。

有关BPMN及其在Activiti中的使用的更多信息,请参阅Activiti 用户指南中的各个部分。

下载onboarding.bpmn20.xml文件,下面的整个XML结构,并将onboarding.bpmn20.xml文件复制到路径$mvnProject/ src / main / resources /。

文件:$ mvnProject /src / main / resources / onboarding.bpmn20.xml

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

<?xml version="1.0"encoding="UTF-8"?>

<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:xsd="http://www.w3.org/2001/XMLSchema"xmlns:activiti="http://activiti.org/bpmn"xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC"xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI"typeLanguage="http://www.w3.org/2001/XMLSchema"expressionLanguage="http://www.w3.org/1999/XPath"targetNamespace="http://www.activiti.org/processdef">

<process id="onboarding"name="Onboarding"isExecutable="true">

<startEvent id="startOnboarding"name="Start"activiti:initiator="initiator"></startEvent>

<userTask id="enterOnboardingData"name="Enter Data"activiti:assignee="${initiator}"activiti:candidateGroups="managers">

<extensionElements>

<activiti:formProperty id="fullName"name="Full Name"type="string"></activiti:formProperty>

<activiti:formProperty id="yearsOfExperience"name="Years of Experience"type="long"required="true"></activiti:formProperty>

</extensionElements>

</userTask>

<sequenceFlow id="sid-1337EA98-7364-4198-B5D9-30F5341D6918"sourceRef="startOnboarding"targetRef="enterOnboardingData"></sequenceFlow>

<exclusiveGateway id="decision"name="Years of Experience"default="automatedIntroPath"></exclusiveGateway>

<sequenceFlow id="sid-42BE5661-C3D5-4DE6-96F5-73D34822727A"sourceRef="enterOnboardingData"targetRef="decision"></sequenceFlow>

<userTask id="personalizedIntro"name="Personalized Introduction and DataEntry"activiti:assignee="${initiator}"activiti:candidateGroups="managers">

<extensionElements>

<activiti:formProperty id="personalWelcomeTime"name="Personal Welcome Time"type="date"datePattern="MM-dd-yyyy hh:mm"></activiti:formProperty>

</extensionElements>

</userTask>

<endEvent id="endOnboarding"name="End"></endEvent>

<sequenceFlow id="sid-37A73ACA-2E23-400B-96F3-71F77738DAFA"sourceRef="automatedIntro"targetRef="endOnboarding"></sequenceFlow>

<scriptTask id="automatedIntro"name="Generic and Automated Data Entry"scriptFormat="javascript"activiti:autoStoreVariables="false">

<script><![CDATA[var dateAsString = newDate().toString();

execution.setVariable("autoWelcomeTime", dateAsString);]]></script>

</scriptTask>

<sequenceFlow id="automatedIntroPath"sourceRef="decision"targetRef="automatedIntro"></sequenceFlow>

<sequenceFlow id="personalizedIntroPath"name="&gt;3"sourceRef="decision"targetRef="personalizedIntro">

<conditionExpression xsi:type="tFormalExpression"><![CDATA[${yearsOfExperience > 3}]]></conditionExpression>

</sequenceFlow>

<sequenceFlow id="sid-BA6F061B-47B6-428B-8CE6-739244B14BD6"sourceRef="personalizedIntro"targetRef="endOnboarding"></sequenceFlow>

</process>

<bpmndi:BPMNDiagram id="BPMNDiagram_onboarding">

<bpmndi:BPMNPlane bpmnElement="onboarding"id="BPMNPlane_onboarding">

<bpmndi:BPMNShape bpmnElement="startOnboarding"id="BPMNShape_startOnboarding">

<omgdc:Bounds height="30.0"width="30.0"x="155.0"y="145.0"></omgdc:Bounds>

</bpmndi:BPMNShape>

<bpmndi:BPMNShape bpmnElement="enterOnboardingData"id="BPMNShape_enterOnboardingData">

<omgdc:Bounds height="80.0"width="100.0"x="240.0"y="120.0"></omgdc:Bounds>

</bpmndi:BPMNShape>

<bpmndi:BPMNShape bpmnElement="decision"id="BPMNShape_decision">

<omgdc:Bounds height="40.0"width="40.0"x="385.0"y="140.0"></omgdc:Bounds>

</bpmndi:BPMNShape>

<bpmndi:BPMNShape bpmnElement="personalizedIntro"id="BPMNShape_personalizedIntro">

<omgdc:Bounds height="80.0"width="100.0"x="519.0"y="15.0"></omgdc:Bounds>

</bpmndi:BPMNShape>

<bpmndi:BPMNShape bpmnElement="endOnboarding"id="BPMNShape_endOnboarding">

<omgdc:Bounds height="28.0"width="28.0"x="725.0"y="165.0"></omgdc:Bounds>

</bpmndi:BPMNShape>

<bpmndi:BPMNShape bpmnElement="automatedIntro"id="BPMNShape_automatedIntro">

<omgdc:Bounds height="80.0"width="100.0"x="520.0"y="255.0"></omgdc:Bounds>

</bpmndi:BPMNShape>

<bpmndi:BPMNEdge bpmnElement="sid-37A73ACA-2E23-400B-96F3-71F77738DAFA"id="BPMNEdge_sid-37A73ACA-2E23-400B-96F3-71F77738DAFA">

<omgdi:waypoint x="570.0"y="255.0"></omgdi:waypoint>

<omgdi:waypoint x="570.0"y="179.0"></omgdi:waypoint>

<omgdi:waypoint x="725.0"y="179.0"></omgdi:waypoint>

</bpmndi:BPMNEdge>

<bpmndi:BPMNEdge bpmnElement="sid-1337EA98-7364-4198-B5D9-30F5341D6918"id="BPMNEdge_sid-1337EA98-7364-4198-B5D9-30F5341D6918">

<omgdi:waypoint x="185.0"y="160.0"></omgdi:waypoint>

<omgdi:waypoint x="240.0"y="160.0"></omgdi:waypoint>

</bpmndi:BPMNEdge>

<bpmndi:BPMNEdge bpmnElement="automatedIntroPath"id="BPMNEdge_automatedIntroPath">

<omgdi:waypoint x="405.0"y="180.0"></omgdi:waypoint>

<omgdi:waypoint x="405.0"y="295.0"></omgdi:waypoint>

<omgdi:waypoint x="520.0"y="295.0"></omgdi:waypoint>

</bpmndi:BPMNEdge>

<bpmndi:BPMNEdge bpmnElement="personalizedIntroPath"id="BPMNEdge_personalizedIntroPath">

<omgdi:waypoint x="405.0"y="140.0"></omgdi:waypoint>

<omgdi:waypoint x="405.0"y="55.0"></omgdi:waypoint>

<omgdi:waypoint x="519.0"y="55.0"></omgdi:waypoint>

</bpmndi:BPMNEdge>

<bpmndi:BPMNEdge bpmnElement="sid-42BE5661-C3D5-4DE6-96F5-73D34822727A"id="BPMNEdge_sid-42BE5661-C3D5-4DE6-96F5-73D34822727A">

<omgdi:waypoint x="340.0"y="160.0"></omgdi:waypoint>

<omgdi:waypoint x="385.0"y="160.0"></omgdi:waypoint>

</bpmndi:BPMNEdge>

<bpmndi:BPMNEdge bpmnElement="sid-BA6F061B-47B6-428B-8CE6-739244B14BD6"id="BPMNEdge_sid-BA6F061B-47B6-428B-8CE6-739244B14BD6">

<omgdi:waypoint x="619.0"y="55.0"></omgdi:waypoint>

<omgdi:waypoint x="739.0"y="55.0"></omgdi:waypoint>

<omgdi:waypoint x="739.0"y="165.0"></omgdi:waypoint>

</bpmndi:BPMNEdge>

</bpmndi:BPMNPlane>

</bpmndi:BPMNDiagram>

</definitions>

添加到OnboardingRequest.java,如下图所示:

文件:$ mvnProject /src / main / java / com / example / OnboardingRequest.java

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

package com.example;

import java.text.ParseException;

importorg.activiti.engine.ProcessEngine;

importorg.activiti.engine.ProcessEngineConfiguration;

importorg.activiti.engine.RepositoryService;

importorg.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration;

import org.activiti.engine.repository.Deployment;

importorg.activiti.engine.repository.ProcessDefinition;

publicclassOnboardingRequest {

publicstaticvoidmain(String[] args) throws ParseException {

ProcessEngineConfiguration cfg = new StandaloneProcessEngineConfiguration()

.setJdbcUrl("jdbc:h2:mem:activiti;DB_CLOSE_DELAY=1000")

.setJdbcUsername("sa")

.setJdbcPassword("")

.setJdbcDriver("org.h2.Driver")

.setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);

ProcessEngineprocessEngine = cfg.buildProcessEngine();

String pName =processEngine.getName();

String ver =ProcessEngine.VERSION;

System.out.println("ProcessEngine [" + pName + "] Version: [" + ver + "]");

RepositoryServicerepositoryService = processEngine.getRepositoryService();

Deployment deployment =repositoryService.createDeployment()

.addClasspathResource("onboarding.bpmn20.xml").deploy();

ProcessDefinitionprocessDefinition = repositoryService.createProcessDefinitionQuery()

.deploymentId(deployment.getId()).singleResult();

System.out.println(

"Found process definition ["

+ processDefinition.getName() + "] with id ["

+ processDefinition.getId() + "]");

}

}

文件:$ mvnProject /src / main / java / com / example / OnboardingRequest.java

添加行

说明

25-27

加载提供的BPMN模型并将其部署到Activiti Process Engine。

28-33

检索已部署的模型,证明它位于Activiti存储库中。

通过运行“mvn package”打包代码。

像以前一样运行Java程序。示例输出如下所示。

命令:java -jarActivitiDeveloperQuickStart-0.0.1-SNAPSHOT-jar-with-dependencies.jar

-要么-

java -jar $quickStartJavaProjectName-0.0.1-SNAPSHOT-jar-with-dependencies.jar

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

...

02:01:19,277 [main] INFO org.activiti.engine.impl.ProcessEngineImpl  - ProcessEngine defaultcreated

processEngine [default] version: [5.22.0.0]

...

02:01:19,327 [main] DEBUGorg.activiti.engine.impl.bpmn.deployer.BpmnDeployer  - Processingdeployment null

02:01:19,327 [main] INFO org.activiti.engine.impl.bpmn.deployer.BpmnDeployer  - Processing resourceonboarding.bpmn20.xml

02:01:19,444 [main] DEBUGorg.activiti.engine.impl.bpmn.parser.handler.ProcessParseHandler  -Parsing process

...

02:01:21,696 [main] DEBUGorg.apache.ibatis.datasource.pooled.PooledDataSource  - Returnedconnection 667346055 to pool.

02:01:21,696 [main] DEBUGorg.activiti.engine.impl.interceptor.LogInterceptor  - --- DeployCmdfinished --------------------------------------------------------

...

02:01:21,696 [main] DEBUGorg.activiti.engine.impl.interceptor.LogInterceptor  - --- startingProcessDefinitionQueryImpl--------------------------------------------------------

...

02:01:21,710 [main] DEBUGorg.apache.ibatis.datasource.pooled.PooledDataSource  - Returnedconnection 667346055 to pool.

02:01:21,710 [main] DEBUGorg.activiti.engine.impl.interceptor.LogInterceptor  - ---ProcessDefinitionQueryImpl finished--------------------------------------------------------

02:01:21,710 [main] DEBUGorg.activiti.engine.impl.interceptor.LogInterceptor  -

Found process definition [Onboarding]with id [onboarding:1:4]

笔记:

  • 这里感兴趣的关键输出是列表行,它记录了进程名称“Onboarding”和“onboarding:1:4”的唯一进程ID(包括部署版本)

您的应用程序现在在运行时部署Onboarding进程。

5.运行流程实例

部署的进程可以使用Activiti API来启动,运行,查看历史记录以及以其他方式管理流程实例。此快速入门使用Java代码运行流程实例。

有关使用Restful Services管理流程实例的示例,请参阅Sample Onboarding Quick Start

将Activiti的日志记录级别从DEBUG设置为WARN,如下面的第1行所示。

文件:$ mvnProject /src / main / resources / log4j.properties

1

2

3

4

5

log4j.rootLogger=WARN, ACT

log4j.appender.ACT=org.apache.log4j.ConsoleAppender

log4j.appender.ACT.layout=org.apache.log4j.PatternLayout

log4j.appender.ACT.layout.ConversionPattern=%d{hh:mm:ss,SSS} [%t] %-5p %c %x - %m%n

重要提示:  以下示例代码说明了Activiti基于标准的可嵌入流程引擎的灵活性和强大功能。但是,此代码在错误处理,代码组织和一般设计方面并不代表最佳实践。相反,目的是快速说明许多想法,以便熟悉Activiti的力量。根据您自己的需要重新考虑以下示例。

添加到OnboardingRequest.java,如下图所示:

文件:$ mvnProject /src / main / java / com / example / OnboardingRequest.java

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

package com.example;

import java.text.DateFormat;

import java.text.ParseException;

importjava.text.SimpleDateFormat;

import java.util.Date;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

import java.util.Scanner;

importorg.activiti.engine.FormService;

importorg.activiti.engine.HistoryService;

importorg.activiti.engine.ProcessEngine;

importorg.activiti.engine.ProcessEngineConfiguration;

importorg.activiti.engine.RepositoryService;

importorg.activiti.engine.RuntimeService;

importorg.activiti.engine.TaskService;

importorg.activiti.engine.form.FormData;

importorg.activiti.engine.form.FormProperty;

importorg.activiti.engine.history.HistoricActivityInstance;

importorg.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration;

importorg.activiti.engine.impl.form.DateFormType;

importorg.activiti.engine.impl.form.LongFormType;

importorg.activiti.engine.impl.form.StringFormType;

importorg.activiti.engine.repository.Deployment;

importorg.activiti.engine.repository.ProcessDefinition;

importorg.activiti.engine.runtime.ProcessInstance;

importorg.activiti.engine.task.Task;

publicclassOnboardingRequest {

publicstaticvoidmain(String[] args) throws ParseException {

ProcessEngineConfiguration cfg = new StandaloneProcessEngineConfiguration()

.setJdbcUrl("jdbc:h2:mem:activiti;DB_CLOSE_DELAY=1000")

.setJdbcUsername("sa")

.setJdbcPassword("")

.setJdbcDriver("org.h2.Driver")

.setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);

ProcessEngineprocessEngine = cfg.buildProcessEngine();

String pName =processEngine.getName();

String ver =ProcessEngine.VERSION;

System.out.println("ProcessEngine [" + pName + "] Version: [" + ver + "]");

RepositoryServicerepositoryService = processEngine.getRepositoryService();

Deployment deployment =repositoryService.createDeployment()

.addClasspathResource("onboarding.bpmn20.xml").deploy();

ProcessDefinitionprocessDefinition = repositoryService.createProcessDefinitionQuery()

.deploymentId(deployment.getId()).singleResult();

System.out.println(

"Found process definition ["

+ processDefinition.getName() + "] with id ["

+ processDefinition.getId() + "]");

RuntimeServiceruntimeService = processEngine.getRuntimeService();

ProcessInstanceprocessInstance = runtimeService

.startProcessInstanceByKey("onboarding");

System.out.println("Onboarding process started with processinstance id ["

+processInstance.getProcessInstanceId()

+ "] key [" +processInstance.getProcessDefinitionKey() + "]");

TaskService taskService= processEngine.getTaskService();

FormService formService= processEngine.getFormService();

HistoryServicehistoryService = processEngine.getHistoryService();

Scanner scanner = new Scanner(System.in);

while (processInstance != null &&!processInstance.isEnded()) {

List<Task>tasks = taskService.createTaskQuery()

.taskCandidateGroup("managers").list();

System.out.println("Activeoutstanding tasks: [" + tasks.size() + "]");

for (int i = 0; i < tasks.size(); i++) {

Task task= tasks.get(i);

System.out.println("ProcessingTask [" + task.getName() + "]");

Map<String, Object> variables = new HashMap<String,Object>();

FormDataformData = formService.getTaskFormData(task.getId());

for (FormPropertyformProperty : formData.getFormProperties()) {

if(StringFormType.class.isInstance(formProperty.getType())) {

System.out.println(formProperty.getName() + "?");

String value = scanner.nextLine();

variables.put(formProperty.getId(), value);

} elseif(LongFormType.class.isInstance(formProperty.getType())) {

System.out.println(formProperty.getName() + "? (Must be a whole number)");

Long value = Long.valueOf(scanner.nextLine());

variables.put(formProperty.getId(), value);

} elseif(DateFormType.class.isInstance(formProperty.getType())) {

System.out.println(formProperty.getName() + "? (Must be a date m/d/yy)");

DateFormat dateFormat = new SimpleDateFormat("m/d/yy");

Date value = dateFormat.parse(scanner.nextLine());

variables.put(formProperty.getId(), value);

} else {

System.out.println("<formtype not supported>");

}

}

taskService.complete(task.getId(), variables);

HistoricActivityInstance endActivity = null;

List<HistoricActivityInstance> activities =

historyService.createHistoricActivityInstanceQuery()

.processInstanceId(processInstance.getId()).finished()

.orderByHistoricActivityInstanceEndTime().asc()

.list();

for (HistoricActivityInstanceactivity : activities) {

if(activity.getActivityType() == "startEvent") {

System.out.println("BEGIN" + processDefinition.getName()

+ "[" + processInstance.getProcessDefinitionKey()

+ "]" + activity.getStartTime());

}

if(activity.getActivityType() == "endEvent") {

// Handleedge case where end step happens so fast that the end step

// andprevious step(s) are sorted the same. So, cache the end step 

//anddisplay it last to represent the logical sequence.

endActivity = activity;

} else {

System.out.println("--" + activity.getActivityName()

+ "[" + activity.getActivityId() + "] "

+ activity.getDurationInMillis() + " ms");

}

}

if (endActivity != null) {

System.out.println("--" + endActivity.getActivityName()

+ "[" + endActivity.getActivityId() + "] "

+ endActivity.getDurationInMillis() + " ms");

System.out.println("COMPLETE" + processDefinition.getName() + " ["

+ processInstance.getProcessDefinitionKey() + "] "

+ endActivity.getEndTime());

}

}

// Re-query the process instance, making surethe latest state is available

processInstance =runtimeService.createProcessInstanceQuery()

.processInstanceId(processInstance.getId()).singleResult();

}

scanner.close();

}

}

文件:$ mvnProject /src / main / java / com / example / OnboardingRequest.java

添加行

说明

12-13,17-21,28-39

Activiti API中的主要服务导入用于流程管理。

54-59

启动Onboarding进程的实例。

61-62,67,71-93

从符合“管理员”角色和完成任务的任务中收集命令行输入。

23-25,76,80,84

基于流程模型中定义的表单属性类型,提示用户输入特定于类型的输入。

63,95-125

显示过程历史记录。

23-25

检索已部署的模型,证明它位于Activiti存储库中

通过运行“mvn package”打包代码。

像以前一样运行Java程序。注意下面提到的示例输出。

命令:java -jarActivitiDeveloperQuickStart-0.0.1-SNAPSHOT-jar-with-dependencies.jar

-要么-

java -jar $quickStartJavaProjectName-0.0.1-SNAPSHOT-jar-with-dependencies.jar

基本路径:$ mvnProject

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

ProcessEngine [default] Version: [5.22.0.0]

Found process definition [Onboarding]with id [onboarding:1:4]

Onboarding process started withprocess instance id [5] key [onboarding]

Active outstanding tasks: [1]

Processing Task [Enter Data]

Full Name?

John Doe

Years of Experience? (Must be a wholenumber)

2

BEGIN Onboarding [onboarding] Sun Nov 2721:36:21 EST 2016

-- Start [startOnboarding] 4 ms

-- Enter Data [enterOnboardingData] 16855 ms

-- Years of Experience [decision] 3 ms

-- Generic and Automated Data Entry[automatedIntro] 322 ms

-- End [endOnboarding] 0 ms

COMPLETE Onboarding [onboarding] SunNov 2721:36:38 EST 2016

笔记:

  • 观察2年经验在“经验岁月”决定之后看到脚本任务“通用和自动数据输入”之后的流程路径,然后流程结束。

命令:java -jar ActivitiDeveloperQuickStart-0.0.1-SNAPSHOT-jar-with-dependencies.jar

-要么-

java -jar $quickStartJavaProjectName-0.0.1-SNAPSHOT-jar-with-dependencies.jar

基本路径:$ mvnProject

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

ProcessEngine [default] Version: [5.22.0.0]

Found process definition [Onboarding]with id [onboarding:1:4]

Onboarding process started withprocess instance id [5] key [onboarding]

Active outstanding tasks: [1]

Processing Task [Enter Data]

Full Name?

John Doe

Years of Experience? (Must be a wholenumber)

5

BEGIN Onboarding [onboarding] Sun Nov 2721:39:26 EST 2016

-- Start [startOnboarding] 5 ms

-- Enter Data [enterOnboardingData] 7810 ms

-- Years of Experience [decision] 2 ms

Active outstanding tasks: [1]

Processing Task [PersonalizedIntroduction and Data Entry]

Personal Welcome Time? (Must be a datem/d/yy)

12/9/16

BEGIN Onboarding [onboarding] Sun Nov 2721:39:26 EST 2016

-- Start [startOnboarding] 5 ms

-- Enter Data [enterOnboardingData] 7810 ms

-- Years of Experience [decision] 2 ms

-- Personalized Introduction and DataEntry [personalizedIntro] 20231 ms

-- End [endOnboarding] 0 ms

COMPLETE Onboarding [onboarding] SunNov 2721:39:54 EST 2016

笔记:

  • 观察5年经验在“经验岁月”决定之后看到用户任务“个性化介绍和数据输入”之后的流程路径。然后过程结束。

虽然简单,但这个嵌入式示例显示了您的应用程序如何将流程逻辑外部化为基于标准的建模和代码友好的开发模型。

6.用Java编写服务任务

如前所述,我们的流程有一个活动“通用和自动数据输入”(一种虚假的后端调用),当入门年经验不超过3时,它有条件地运用。如所提供的,这是一个“脚本任务”。在这种情况下,执行了一小段Javascript,说明了系统处理步骤。我们将把这个脚本任务迁移到Java中,以说明Java的全部功能如何满足各种流程要求。

创建一个新的Java类,如下所示:

文件:$ mvnProject /src / main / java / com / example / AutomatedDataDelegate.java

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

package com.example;

import java.util.Date;

importorg.activiti.engine.delegate.DelegateExecution;

importorg.activiti.engine.delegate.JavaDelegate;

publicclassAutomatedDataDelegate implements JavaDelegate {

@Override

publicvoidexecute(DelegateExecutionexecution) throws Exception {

Date now = new Date();

execution.setVariable("autoWelcomeTime", now);

System.out.println("Faux call to backend for ["

+ execution.getVariable("fullName") + "]");

}

}

文件:$ mvnProject /src / main / java / com / example / OnboardingRequest.java

添加行

说明

13

显示设置过程变量。在这种情况下,变量autoWelcomeTime与当前时间。

14

显示检索流程变量。

将脚本任务更改为指向AutomatedDataDelegate的服务任务。

之前:

文件:$ mvnProject /src / main / resources / onboarding.bpmn20.xml

1

2

3

4

5

6

7

8

9

<?xml version="1.0"encoding="UTF-8"?>

<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:xsd="http://www.w3.org/2001/XMLSchema"xmlns:activiti="http://activiti.org/bpmn"xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC"xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI"typeLanguage="http://www.w3.org/2001/XMLSchema"expressionLanguage="http://www.w3.org/1999/XPath"targetNamespace="http://www.activiti.org/processdef">

<process id="onboarding"name="Onboarding"isExecutable="true">

...

<scriptTask id="automatedIntro"name="Generic and Automated Data Entry"scriptFormat="javascript"activiti:autoStoreVariables="false">

<script><![CDATA[var dateAsString = newDate().toString();

execution.setVariable("autoWelcomeTime", dateAsString);]]></script>

</scriptTask>

...

后:

文件:$ mvnProject /src / main / resources / onboarding.bpmn20.xml

1

2

3

4

5

<?xml version="1.0" encoding="UTF-8"?>

<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:xsd="http://www.w3.org/2001/XMLSchema"xmlns:activiti="http://activiti.org/bpmn"xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC"xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI"typeLanguage="http://www.w3.org/2001/XMLSchema"expressionLanguage="http://www.w3.org/1999/XPath"targetNamespace="http://www.activiti.org/processdef">

<process id="onboarding"name="Onboarding"isExecutable="true">

...

<serviceTask id="automatedIntro"name="Generic and Automated Data Entry"activiti:class="com.example.AutomatedDataDelegate"></serviceTask>

通过运行“mvn package”打包代码。

像以前一样运行Java程序。注意下面提到的示例输出。

命令:java -jarActivitiDeveloperQuickStart-0.0.1-SNAPSHOT-jar-with-dependencies.jar

-要么-

java -jar $quickStartJavaProjectName-0.0.1-SNAPSHOT-jar-with-dependencies.jar

基本路径:$ mvnProject

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

ProcessEngine [default] Version: [5.22.0.0]

Found process definition [Onboarding]with id [onboarding:1:4]

Onboarding process started withprocess instance id [5] key [onboarding]

Active outstanding tasks: [1]

Processing Task [Enter Data]

Full Name?

John Doe

Years of Experience? (Must be a wholenumber)

3

Faux call to backend for [John Doe]

BEGIN Onboarding [onboarding] Sun Nov 2722:57:32 EST 2016

-- Start [startOnboarding] 4 ms

-- Enter Data [enterOnboardingData] 10153 ms

-- Years of Experience [decision] 2 ms

-- Generic and Automated Data Entry[automatedIntro] 0 ms

-- End [endOnboarding] 0 ms

COMPLETE Onboarding [onboarding] SunNov 2722:57:42 EST 2016

笔记:

  • 观察输出“[John Doe]后端的虚假调用”,说明访问先前设置的过程变量。

这个简单的例子展示了在应用程序中添加流程驱动抽象的简单性和强大功能。

7.结论

观察输出“[John Doe]后端的虚假调用”,说明访问先前设置的过程变量。

源代码:https://github.com/daqiang123/ActivitiDeveloperQuickStart.git

Activiti6快速入门指南相关推荐

  1. BERT模型超酷炫,上手又太难?请查收这份BERT快速入门指南!

    点击上方"AI遇见机器学习",选择"星标"公众号 重磅干货,第一时间送达 来自 | GitHub    作者 | Jay Alammar 转自 | 机器之心 如 ...

  2. BERT模型超酷炫,上手又太难?请查收这份BERT快速入门指南

    2019-12-31 10:50:59 选自GitHub 作者:Jay Alammar 参与:王子嘉.Geek AI 如果你是一名自然语言处理从业者,那你一定听说过最近大火的 BERT 模型.本文是一 ...

  3. RMAN快速入门指南

    RMAN快速入门指南   1. What is RMAN? 什么是RMAN?    4 2. Terminology 专业词汇解释    4 2.1. Backup sets 备份集合    4 2. ...

  4. 150页书籍《PyTorch 深度学习快速入门指南》附PDF电子版

    为什么说是极简教程,首先本书只涵盖了150页.内容比较精简,特别适合作为 PyTorch 深度学习的入门书籍.为什么这么说呢?因为很多时候,一份厚重的书籍往往会削弱我们学习的积极性,在学习一门新的语言 ...

  5. h5py快速入门指南

    h5py是Python语言用来操作HDF5的模块.下面的文章主要介绍h5py的快速入门指南,翻译自h5py的官方文档:http://docs.h5py.org/en/lates... .该翻译仅为个人 ...

  6. 2017 Vue.js 2快速入门指南

    注意,据部分读者反映本文水多,怕湿身者勿进.后续推荐详解 Vue & Vuex 实践 2017 Vue.js 2快速入门指南翻译自Vue.js 2 Quickstart Tutorial 20 ...

  7. Flux快速入门指南

    翻译自 http://www.jackcallister.com/2015/02/26/the-flux-quick-start-guide.html 2015年2月26日 本文将概述如何使用Flux ...

  8. AngularJS快速入门指南09:SQL

    我们可以将之前章节中的代码用来从数据库中读取数据. 通过PHP Server从MySQL数据库中获取数据 <div ng-app="myApp" ng-controller= ...

  9. AngularJS快速入门指南03:表达式

    AngularJS通过表达式将数据绑定到HTML. AngularJS表达式 AngularJS表达式写在双大括号中:{{ 表达式语句 }}. AngularJS表达式绑定数据到HTML的方式与ng- ...

  10. AngularJS快速入门指南15:API

    API即Application Programming Interface(应用程序接口). AngularJS全局API AngularJS全局API是一组全局JavaScript函数,用来进行一些 ...

最新文章

  1. 疫情期间用掉了1400亿个!二维码会被人类扫完吗?
  2. 详解数据中台构建核心产品Dataphin“ 规划”能力
  3. matlab中prprob,pr-sr-master
  4. linux目录硬链接,linux查看硬链接对应的所有文件
  5. 设计模式17_命令模式
  6. 定义一个复数类Complex,重载运算符“+”,
  7. c语言如何写出高清的录屏软件,电脑可以实现高清录屏的软件有哪些?看完你就明白了...
  8. 单片机开发怎么把杜邦线弄整齐?
  9. 论文阅读《Revisiting Domain Generalized Stereo Matching Networks from a Feature Consistency Perspective》
  10. iOS组件化方案对比
  11. Element UI学习6--Carousel 走马灯
  12. opencv VideoWriter保存摄像头视频、本地视频等
  13. 2020外地人如何把户口迁入广州
  14. C++数组去重与排序
  15. [车联网安全自学篇] ATTACK安全之Frida反调试检测
  16. 雷达有源干扰——噪声卷积干扰
  17. cocos creator 支持gif
  18. 如何在unity中debug调试打包到VR头显的应用代码
  19. 300㎡现代新中式别墅,诠释淡雅的东方美学。
  20. 后端给一个菜单的全数组,组合成树类型的菜单

热门文章

  1. 2020年中国洪涝受灾人口数、死亡失踪人口数、倒塌房屋数量及造成的直接经济损失分析[图]
  2. java-Socket文件传输
  3. html页面改成wap页面,wap网页怎么制作 这五大常见问题你要了解一下了!
  4. CocosBuilder 的使用
  5. 用C语言开发一个BT下载软件 (四) ------ 代码实现-1-种子文件解析模块
  6. Java小程序:单循环比赛,总分高者获胜的源代码
  7. 参考文献引用格式实例
  8. 【阿里技术】2019年开发者必读!20位阿里技术大牛们帮你列了一份经典书单!
  9. 转发:大学课本答案大全!爱死你了…
  10. 汉字与GBK内码互转工具(支持批量转换)