Hello World BPMN2.0またはActivitiの紹介

この記事では、Activitiエンジンを使用して簡単なアプリケーションを作成する例を検討します。



Activiti 」は、ビジネスプロセス(ビジネスプロセス管理)を操作するための軽量プラットフォームであり、ビジネスマン、開発者、およびシステム管理者に適合しています。 このプラットフォームは、 BPMN2プロセスの高速で信頼性の高いJavaエンジンに基づいています 。 OpenSourceプロジェクトは、Apacheライセンスの下で配布されています。 Activitiは、Javaアプリケーションの一部として、またはサーバー、クラスター、クラウド上で個別に起動できます。 さらに、Springと完全に統合されます。



プロジェクトには優れたドキュメントがあるため、基本的な概念については説明しません。 上記のように、Activitiをスタンドアロンアプリケーションとして使用できますが、アプリケーションに埋め込まれたビジネスプロセスを処理するためのエンジン/ライブラリとして使用できます。 詳細はこちらをご覧ください



依存関係



それでは、始めましょう。 まず、Mavenをサポートするプロジェクトを作成し、その中に次の依存関係を記述する必要があります。



<!--

Activiti

-->

< dependency >

< groupId > org.activiti </ groupId >

< artifactId > activiti-engine </ artifactId >

< version > 5.1 </ version >

</ dependency >

< dependency >

< groupId > org.activiti </ groupId >

< artifactId > activiti-spring </ artifactId >

< version > 5.1 </ version >

</ dependency >





<!--

DataBase

-->

< dependency >

< groupId > com.h2database </ groupId >

< artifactId > h2 </ artifactId >

< version > 1.2.132 </ version >

</ dependency >

< dependency >

< groupId > commons-dbcp </ groupId >

< artifactId > commons-dbcp </ artifactId >

< version > 1.2.2 </ version >

</ dependency >





* This source code was highlighted with Source Code Highlighter .








最初の2つの依存関係(mavenのリポジトリについてはここで説明します )は、ActivitiカーネルとSpringとの統合のためのユーティリティセットを接続します(Springの接続は、スペースを節約するために説明していません) 依存関係の2番目のグループは、データベース(この場合、インメモリが使用されます)とそれを操作するためのプールを接続します。



Activitiには、プロセス、そのステータス、ユーザー、履歴、その他に関する情報を保存するデータベースが必要です。



業務プロセス



ビジネスプロセスの説明を使用してアプリケーションの開発を開始することは論理的です。 まず、Activitiが提供するビジネスプロセス記述の単位 (より正確には、 BPMN 2.0表記)を理解する必要があります。 その後、独自のビジネスプロセスの説明を開始できます。 これを行うには3つの方法があります。



3番目の点が上記の中で最も論理的であると思われるという事実にもかかわらず、CASEテクノロジーを使用し、Eclipse用のプラグインを使用してビジネスプロセスを描画します(ダイアグラムを変更するたびにxml-descriptionを更新するようにプラグイン設定を設定することが重要です。自分自身の生活とユーザーとしての外部刺激を完全に無視します)。



その結果、次の図が得られました。



図



ServiceTask“ GenerateData”は擬似ランダムデータを生成します(JavaDelegateインターフェースを実装するGenerateDataServiceクラスを使用した実装)



@Service

public class GenerateDataService implements JavaDelegate {



public void execute(DelegateExecution execution) throws Exception {

Long someData = Calendar.getInstance().getTimeInMillis() % 2;

execution.setVariable( "someData" , someData);

}

}




* This source code was highlighted with Source Code Highlighter .








ServiceTask「SayHelloA」またはServiceTask「SayHelloB」のどちらが実行されるかに応じて。 これらのServiceTaskは両方とも、対応するSayHelloServiceサービスメソッドを呼び出すことになります( UEL式 「$ {sayHelloService.printMessageB(execution)」に基づく実装):



@Service

public class SayHelloService {



public void printMessageA(ActivityExecution execution) {

System. out .println( "Hello world: variant A" );

}



public void printMessageB(ActivityExecution execution) {

System. out .println( "Hello world: variant B" );

}

}




* This source code was highlighted with Source Code Highlighter .








XML形式(つまり、BPMN 2.0の形式)、つまり、Activitiエンジンが解釈に必要な場合、プロセスは次のとおりです。



<? 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: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/test" >



< process id ="helloWorldProcess" name ="Hello World" >

< documentation > Simple "Hello World" process </ documentation >

< startEvent id ="startevent1" name ="Start" ></ startEvent >

< serviceTask id ="servicetask1" name ="GenerateData" activiti:class ="name.krestjaninoff.activiti.hello.process.GenerateDataService" ></ serviceTask >

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

< sequenceFlow id ="flow1" name ="" sourceRef ="startevent1" targetRef ="servicetask1" ></ sequenceFlow >

< serviceTask id ="servicetask3" name ="SayHelloB" activiti:expression ="${sayHelloService.printMessageB(execution)}" ></ serviceTask >

< serviceTask id ="servicetask4" name ="SayHelloA" activiti:expression ="${sayHelloService.printMessageA(execution)}" ></ serviceTask >

< exclusiveGateway id ="exclusivegateway2" name ="Exclusive Gateway" ></ exclusiveGateway >

< sequenceFlow id ="flow4" name ="" sourceRef ="servicetask1" targetRef ="exclusivegateway2" ></ sequenceFlow >

< sequenceFlow id ="flow5" name ="${someData != 0}" sourceRef ="exclusivegateway2" targetRef ="servicetask3" >

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

</ sequenceFlow >

< sequenceFlow id ="flow6" name ="${someData == 0}" sourceRef ="exclusivegateway2" targetRef ="servicetask4" >

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

</ sequenceFlow >

< exclusiveGateway id ="exclusivegateway3" name ="Exclusive Gateway" ></ exclusiveGateway >

< sequenceFlow id ="flow7" name ="" sourceRef ="servicetask3" targetRef ="exclusivegateway3" ></ sequenceFlow >

< sequenceFlow id ="flow8" name ="" sourceRef ="servicetask4" targetRef ="exclusivegateway3" ></ sequenceFlow >

< sequenceFlow id ="flow9" name ="" sourceRef ="exclusivegateway3" targetRef ="endevent1" ></ sequenceFlow >

</ process >



< bpmndi:BPMNDiagram id ="BPMNDiagram_helloWorldProcess" >

< bpmndi:BPMNPlane bpmnElement ="helloWorldProcess" id ="BPMNPlane_helloWorldProcess" >

< bpmndi:BPMNShape bpmnElement ="startevent1" id ="BPMNShape_startevent1" >

< omgdc:Bounds height ="55" width ="55" x ="273" y ="10" ></ omgdc:Bounds >

</ bpmndi:BPMNShape >

< bpmndi:BPMNShape bpmnElement ="servicetask1" id ="BPMNShape_servicetask1" >

< omgdc:Bounds height ="55" width ="105" x ="248" y ="120" ></ omgdc:Bounds >

</ bpmndi:BPMNShape >

< bpmndi:BPMNShape bpmnElement ="endevent1" id ="BPMNShape_endevent1" >

< omgdc:Bounds height ="55" width ="55" x ="273" y ="460" ></ omgdc:Bounds >

</ bpmndi:BPMNShape >

< bpmndi:BPMNShape bpmnElement ="servicetask3" id ="BPMNShape_servicetask3" >

< omgdc:Bounds height ="55" width ="105" x ="390" y ="304" ></ omgdc:Bounds >

</ bpmndi:BPMNShape >

< bpmndi:BPMNShape bpmnElement ="servicetask4" id ="BPMNShape_servicetask4" >

< omgdc:Bounds height ="55" width ="105" x ="109" y ="304" ></ omgdc:Bounds >

</ bpmndi:BPMNShape >

< bpmndi:BPMNShape bpmnElement ="exclusivegateway2" id ="BPMNShape_exclusivegateway2" >

< omgdc:Bounds height ="60" width ="60" x ="270" y ="210" ></ omgdc:Bounds >

</ bpmndi:BPMNShape >

< bpmndi:BPMNShape bpmnElement ="exclusivegateway3" id ="BPMNShape_exclusivegateway3" >

< omgdc:Bounds height ="60" width ="60" x ="270" y ="370" ></ omgdc:Bounds >

</ bpmndi:BPMNShape >

< bpmndi:BPMNEdge bpmnElement ="flow1" id ="BPMNEdge_flow1" >

< omgdi:waypoint x ="328" y ="37" ></ omgdi:waypoint >

< omgdi:waypoint x ="248" y ="147" ></ omgdi:waypoint >

</ bpmndi:BPMNEdge >

< bpmndi:BPMNEdge bpmnElement ="flow4" id ="BPMNEdge_flow4" >

< omgdi:waypoint x ="353" y ="147" ></ omgdi:waypoint >

< omgdi:waypoint x ="270" y ="240" ></ omgdi:waypoint >

</ bpmndi:BPMNEdge >

< bpmndi:BPMNEdge bpmnElement ="flow5" id ="BPMNEdge_flow5" >

< omgdi:waypoint x ="330" y ="240" ></ omgdi:waypoint >

< omgdi:waypoint x ="390" y ="331" ></ omgdi:waypoint >

</ bpmndi:BPMNEdge >

< bpmndi:BPMNEdge bpmnElement ="flow6" id ="BPMNEdge_flow6" >

< omgdi:waypoint x ="330" y ="240" ></ omgdi:waypoint >

< omgdi:waypoint x ="109" y ="331" ></ omgdi:waypoint >

</ bpmndi:BPMNEdge >

< bpmndi:BPMNEdge bpmnElement ="flow7" id ="BPMNEdge_flow7" >

< omgdi:waypoint x ="495" y ="331" ></ omgdi:waypoint >

< omgdi:waypoint x ="270" y ="400" ></ omgdi:waypoint >

</ bpmndi:BPMNEdge >

< bpmndi:BPMNEdge bpmnElement ="flow8" id ="BPMNEdge_flow8" >

< omgdi:waypoint x ="214" y ="331" ></ omgdi:waypoint >

< omgdi:waypoint x ="270" y ="400" ></ omgdi:waypoint >

</ bpmndi:BPMNEdge >

< bpmndi:BPMNEdge bpmnElement ="flow9" id ="BPMNEdge_flow9" >

< omgdi:waypoint x ="330" y ="400" ></ omgdi:waypoint >

< omgdi:waypoint x ="273" y ="487" ></ omgdi:waypoint >

</ bpmndi:BPMNEdge >

</ bpmndi:BPMNPlane >

</ bpmndi:BPMNDiagram >

</ definitions >



* This source code was highlighted with Source Code Highlighter .








設定



ここで、Activitiを使用してプロセスを開始するには、Activityのコアの基本要素構成および初期化する必要があります 。 Springを使用しているため、構成は対応するBeanの構成に縮小されます。



< beans xmlns ="http://www.springframework.org/schema/beans"

xmlns:context ="http://www.springframework.org/schema/context"

xmlns:tx ="http://www.springframework.org/schema/tx"

xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation ="http://www.springframework.org/schema/beans www.springframework.org/schema/beans/spring-beans.xsd

www.springframework.org/schema/context www.springframework.org/schema/context/spring-context-3.0.xsd

www.springframework.org/schema/tx www.springframework.org/schema/tx/spring-tx-3.0.xsd"


>

<!-- Configuration -->

< context:property-placeholder location ="classpath*:*.properties" />



<!-- Annotation based configuration -->

< context:annotation-config />

< context:component-scan base-package ="name.krestjaninoff" />





<!-- Data -->

< bean id ="dataSource"

class ="org.apache.commons.dbcp.BasicDataSource" destroy-method ="close" >

< property name ="driverClassName" value ="org.h2.Driver" />

< property name ="url" value ="jdbc:h2:mem:activiti;DB_CLOSE_DELAY=1000" />

< property name ="username" value ="sa" />

< property name ="password" value ="" />

</ bean >



< bean id ="transactionManager"

class ="org.springframework.jdbc.datasource.DataSourceTransactionManager" >

< property name ="dataSource" ref ="dataSource" />

</ bean >

< tx:annotation-driven transaction-manager ="transactionManager" />





<!--

Activiti

-->

< bean id ="processEngineConfiguration" class ="org.activiti.spring.SpringProcessEngineConfiguration" >

< property name ="databaseType" value ="h2" />

< property name ="dataSource" ref ="dataSource" />

< property name ="transactionManager" ref ="transactionManager" />

< property name ="databaseSchemaUpdate" value ="true" />

< property name ="jobExecutorActivate" value ="false" />

< property name ="deploymentResources" value ="classpath*:/process/*.bpmn20.xml" />

</ bean >



< bean id ="processEngine" class ="org.activiti.spring.ProcessEngineFactoryBean" >

< property name ="processEngineConfiguration" ref ="processEngineConfiguration" />

</ bean >



< bean id ="repositoryService" factory-bean ="processEngine"

factory-method ="getRepositoryService" />

< bean id ="runtimeService" factory-bean ="processEngine"

factory-method ="getRuntimeService" />

< bean id ="taskService" factory-bean ="processEngine"

factory-method ="getTaskService" />

< bean id ="historyService" factory-bean ="processEngine"

factory-method ="getHistoryService" />

< bean id ="managementService" factory-bean ="processEngine"

factory-method ="getManagementService" />

</ beans >




* This source code was highlighted with Source Code Highlighter .








processEngineConfiguration BeanのdeploymentResourcesプロパティに注意することが重要です。これは、コンフィギュレーターにプロセスの記述ファイルの場所を伝えます。 アプリケーションを起動するたびに、これらのプロセスをActivitiエンジンに「展開」する必要があります。 詳細な展開については、 ここで説明します



アプリケーションの起動



そのため、主要な作業はすでに完了しています。 これで、アプリケーションを起動するために、Springコンテキストを作成し、目的のプロセスを開始するだけです。



public class Main {

public static void main( String [] args) {



// Create Spring context

ClassPathXmlApplicationContext applicationContext =

new ClassPathXmlApplicationContext( "applicationContext.xml" );



// Start process

RuntimeService runtimeService = (RuntimeService) applicationContext.

getBean( "runtimeService" );

runtimeService.startProcessInstanceByKey( "helloWorldProcess" );

}

}




* This source code was highlighted with Source Code Highlighter .










上記のプロジェクトのコードはGitHubで入手できます



All Articles