Use spring to create a simple workflow engine _java programming

Source: Internet
Author: User
Tags error handling event listener xsl ticket jboss jboss application server mail account mule esb
Article Source: Matrix Author: Steve Dodge

Spring is a relatively new framework to support the control reversal programming mechanism. This article takes spring as a simple workflow engine and uses it in a more generic place. After a brief introduction to the workflow, you will introduce the use of the workflow APIs based on spring in the basic workflow scenario.

Many Java EE applications require a process to be executed in a context separate from the host. In many cases, these background processes perform multiple tasks, and some tasks depend on the state of the previous task. Because of the interdependent relationship between these processing tasks, the use of a set of process based method calls often fails to meet the requirements. With spring, developers can easily detach a background process into an active collection. The spring container connects these activities and organizes them into simple workflows.

In this article, a simple workflow is defined as a collection of arbitrary activities that do not require user intervention to execute in a certain order. However, we do not recommend this approach as a substitute for the existing workflow framework. In some scenarios where more user interaction is required, such as a shift, connection, or transmission based on user input, the better approach is to match a separate open source or business workflow engine. An open source project has successfully integrated more complex workflow designs into spring.

If the workflow task on your hand is simple, then a simple workflow strategy will make sense compared to a fully functional, stand-alone workflow framework, especially if you have already used spring, which ensures that time does not grow longer. In addition, spring has reduced resource load on resource loads, given the characteristics of spring's lightweight control reversal container.

This article briefly describes workflows from the perspective of programming topics. By using the concept of workflows, spring is used as a framework for driving the workflow engine. Then, the production deployment options are discussed. Now let's introduce the idea of a simple workflow from the design pattern of workflow and related background information.

Simple Workflows
The workflow model is a topic that has been studied in the early 70 and many developers have tried to create workflow model specifications. W.h.m van der Aalst and others wrote the workflow model white paper (July 2003), which successfully refines a set of design patterns that accurately model most common workflow scenarios. The most common workflow mode is sequential mode (Sequence pattern). The sequential workflow pattern satisfies the design principle of a simple workflow and consists of a set of activities that are executed sequentially.

UML (Unified Modeling Language) activity diagrams are often used as a mechanism for modeling workflows. Figure 1 shows a basic modeling process that uses a standard UML activity diagram for sequential workflow processes.

Figure 1 Sequential Workflow mode

Sequential workflow is a standard workflow mode that is popular in Java EE. Java EE applications in background threads, usually require some sequence of events or asynchronous events. The activity diagram in Figure 2 depicts a simple workflow that informs interested travellers that they are interested in an event where the ticket price has dropped.

Figure 2. A simple workflow for falling ticket prices

The routing workflow in Figure 1 is responsible for creating and sending dynamic email notifications. Each step in the process represents an activity. Some additional events must occur before the workflow is active. In this case, the incident is a reduction in the rate of flight routes.

Let's take a brief look at the business logic of the route workflow. If the first activity cannot find a user who is interested in the rate reduction notification, the entire workflow is canceled. If an interested user is found, the following activities continue to execute. Subsequently, an XSL (extended stylesheet) transformation generates the message content, after which the audit information (audit information) is recorded. Finally, the workflow attempts to send this message through the SMTP server. If this task is not completed incorrectly, the successful information is recorded in the log, and the process ends. However, if an error occurs while communicating with the SMTP server, a special error-handling routine will manage these errors. The error-handling code will try to resend the message.

One obvious question to consider for this route is: how do you effectively break down sequential processes into separate activities? The problem was cleverly handled by spring. Next, let's quickly discuss spring's reverse control framework.
Control Reversal
Spring is responsible for controlling dependencies between objects by using the spring container, so that we are no longer responsible for dependencies between objects. The realization of this dependency relationship is known as the control reversal (IoC) or dependency injection. See Martin Fowler ' s "inversion of control containers and the Dependency injection pattern" (, February 2004) A more in-depth discussion of reversal and dependency injection. By managing dependencies between objects, spring does not need code that glues objects only to enable classes to collaborate with one another.

Workflow components as spring beans
Before further discussion, it is time to briefly introduce the main concepts in spring. The interface ApplicationContext is inherited from the interface Beanfactory and is used as the actual control entity and container within the spring container.

ApplicationContext is responsible for initializing, configuring, and lifecycle management of a set of beans as a spring beans. We configure ApplicationContext by assembling the spring beans in an xml-based configuration file. This configuration file illustrates the essential features of the spring beans collaboration. Thus, in spring terms, the spring beans interacting with other spring beans is called a collaborator (collaborators). By default, spring beans exists as a single case in ApplicationContext, but the single instance's properties can be set to false to effectively change their behavior when invoking the prototype pattern in spring.

Back to our example, the abstraction of an SMTP send routine is assembled in the workflow process example in the final activity (example code can be obtained in resources) at the time of the airplane fare drop. Since it is the 5th activity, we name it activity5. To send a message, ACTIVITY5 requires a proxy collaborator and a misaligned handle.

<bean id= "Activity5" class= "Org.iocworkflow.test.sequence.ratedrop.SendMessage" > <property name= "Delegate" "> <ref bean=" smtpsenderdelegate "></ref> </property> <property name=" ErrorHandler "> < Ref bean= "Mailerrorhandler"/> </property> </bean>

Implementing the workflow component into Spring beans produces two pleasing results, which are easy to unit test and to a large extent reusable. The features of the IOC container clearly provide effective unit testing. Using an IOC container like spring, the dependencies between collaborators can be easily replaced by false replacements during testing. In the example of this route, a spring bean like activity5 activity can easily be retrieved from a unique test applicationcontext. With a fake SMTP proxy SMTP server, it is possible to test activity5 individually.

The second unintended result is that the reusable capability is implemented through workflow activities such as XSL transformations. An XSL transformation that is abstracted into a workflow activity can now be reused by any workflow that handles XSL transformations.

Assembling workflows
In the API provided (downloaded from resources), spring controls how some operators interact with one workflow. The key interfaces are as follows:

Activity: Encapsulates a single step business logic in a workflow

Processcontext: Passing objects with Processcontext types between workflow activities. The object that implements this interface is responsible for maintaining the state of the object transitioning from one activity to another in the workflow transformation.

ErrorHandler: Provides a callback method for error handling.

Processor: Describes a bean that acts as the performer of the main workflow streamline.

The following code excerpt from the example source is the configuration of the spring bean that assembles the route example into a simple workflow process.

<!--Airline rate drop as a simple sequence workflow process-->
<bean id= "Ratedropprocessor" class= "Org.iocworkflow.SequenceProcessor" >
<property name= "Activities" >
<ref bean= "activity1"/><!--build recipients-->
<ref bean= "Activity2"/><!--construct DOM tree-->
<ref bean= "Activity3"/><!--Apply XSL transform-->
<ref bean= "Activity4"/><!--Write Audit data-->
<ref bean= "Activity5"/><!--attempt to send message-->
<property name= "Defaulterrorhandler" >
<ref bean= "Defaulterrorhandler" ></ref>
<property name= "Processcontextclass" >

The Sequenceprocessor class is a concrete subclass of a sequential pattern modeling. There are 5 activities connected to the workflow processor, and the workflow processor will perform these 5 activities sequentially.

Workflow solutions really highlight highly robust error handling compared to most procedural background processes. An error-handling handle can handle each activity individually. This type of handle provides meticulous error handling at a single activity level. If you do not handle a single active error handling handle alone, the error handling handle of the global workflow processor will handle the problem that occurs. For example, if an unhandled error occurs at any point in the workflow process, it will propagate outward and be processed by the ErrorHandler bean that is assembled using the Defaulterrorhandler attribute.

A more complex workflow framework stores the state of a workflow transition to a database. In this article, we are only interested in the workflow where the state transitions are automatically completed. State information is only available in Processcontext when the actual workflow is running. In Processcontext, you can only see two methods of Processcontext interfaces:

Public interface Processcontext extends Serializable
public boolean stopprocess ();
public void Setseeddata (Object seedobject);

The specific Processcontext class used for the route example workflow is the Ratedropcontext class. The Ratedropcontext class encapsulates the data that is required to perform route rates to reduce workflows.

Until now, all bean instances have been taken as a single case by default ApplicationContext. However, for each route workflow call, we must create a new instance of the Ratedropcontext class. To handle this requirement, you need to configure Sequenceprocessor, using the fully qualified class masterpiece as the value of the Processcontextclass attribute. For the execution of each workflow, Sequenceprocessor retrieves a new instance of the Processorcontext class from spring using the specified class name. In order for this mechanism to work, a prototype that is not a single piece of spring bean or type org.iocworkflow.test.sequence.simple.SimpleContext must exist in ApplicationContext.

Seeding Workflow
Now that we know how to use spring to assemble a simple workflow, let's focus on the process of using the SEED Data sample workflow. To figure out how to start a workflow, look at the ways you can perform on the actual interface processor:

public interface Processor
Public Boolean supports (activity activity);
public void doactivities ();
public void Doactivities (Object seeddata);
public void Setactivities (List activities);
public void Setdefaulterrorhandler (ErrorHandler defaulterrorhandler);

In most cases, the workflow requires some initialization activation to begin. There are two options for starting a process: the Doactivities (Objectseeddata) method or the Doactivities () without parameters. The following code list is the Doactivities () that is included in the sample code for SEQUENCEPROCESSOR implementation:

public void Doactivities (Object seeddata)
Retrieve injected by Spring
List activities = Getactivities ();
Retrieve a new instance of the Workflow Processcontext
Processcontext context = Createcontext ();
if (seeddata!= null)
Context.setseeddata (Seeddata);
Execute each activity in sequential order
for (Iterator it = Activities.iterator (); It.hasnext ();)
Activity activity = (activity) ();
try {
Context = Activity.execute (context);
catch (Throwable th) {
Determine if an error handler be available at the activity level
ErrorHandler ErrorHandler = Activity.geterrorhandler ();
if (ErrorHandler = = null) {
Getdefaulterrorhandler (). HandleError (context, TH);
else {
Handle Error using default handler
Errorhandler.handleerror (context, TH);
Ensure it ' s OK to continue the process
if (processshouldstop (context, activity))

In this example of an airline cost reduction, the seed data for the workflow process includes information on route information and rate reductions. Using an easily tested route workflow example, it is simple to emit seed data through the doactivities (Object Seeddata) method and activate a single workflow process:

Baseprocessor processor = (baseprocessor) context.getbean ("Ratedropprocessor");
Processor.doactivities (Createseeddata ());

The code is extracted from the test examples contained in this article. The Ratedropprocessor Bean was retrieved from the ApplicationContext. Ratedropprocessor are actually assembled into sequenceprocessor instances to handle sequential execution. The Createseeddata () method instantiates an object that encapsulates all the seed data required to initialize the route workflow.

Processor Options
Although the processor specific subclasses contained in the source code are just sequenceprocessor, the implementation of many processor interfaces is also conceivable. Other workflow process subclasses can be developed to control different workflow types, for example, another workflow that has a changing execution path like the parallel cut pattern. For simple workflows, because the order of the activities is predetermined, sequenceprocessor is a good choice. Although not included, an exclusive selection pattern is another good choice for an implementation that uses a simple workflow based on spring. When an exclusive selection mode is used, after each activity is executed, the processor specific class will interrogate processorcontext and then which activity will be performed.

Note: For more information on parallel cutting, exclusive selection, and other workflow patterns, see W.M.P. Van der Aalst and other people wrote the book "Workflow mode."

Start a workflow
Considering that workflow processes often require asynchronous execution, it makes sense to use a separate execution thread to start a workflow. There are several options for the asynchronous startup of a workflow; we focus on two of them: aggressively detecting (actively polling) a queue to start a workflow, or using an ESB (Enterprise service Bus, Enterprise Service Bus (mule) is the event-driven way to start a workflow, and the ESB is an open source project.

Figure 3 and Figure 4 depict two startup strategies. In Figure 3, active detection occurs when the first activity in the workflow frequently checks for resources, such as a data source or POP3 mail account. If the active detection in Figure 3 finds that a task is waiting to be processed, the startup starts.

Figure 3. To start a workflow by active detection

Figure 4, on the other hand, shows the situation where an application using JMS (Java Messaging Service) to put events on the queue. An event listener configured through the ESB receives the event in Figure 4 and starts the workflow so that the workflow process is started.

Figure 4. To start a workflow through an ESB event

Using the sample code provided, let's take a closer look at the active choice of startup mode and event-driven startup.

Active Detection
Active detection is a program that takes less time to start a workflow process. The sequenceprocessor is flexible enough to enable the startup process to be done through a smooth selection effort. Although not satisfactory, active detection is a wise choice in many scenarios where there is no time for the configuration and deployment of an event-driven subsystem.

With spring's scheduledtimertask, detection mode can be easily assembled. The disadvantage is that additional activities must be created to detect. This detection activity must be designed to interrogate certain entities, such as database tables, POP mail accounts, or Web services, and then decide whether new jobs are waiting to be involved in the workflow.

In the example provided, the Pollingtestcase class instantiates a workflow process based on instrumentation. The difference between using an active detection process and an event-driven startup process is that spring supports a doactivities version of the method. Conversely, in event-driven startup, the entity that initiates the process provides seed data through the doactivities (Object seeddata) method to start the workflow. Another drawback of detection methods is that resources are not necessarily reusable. The consumption of such resources is unacceptable, depending on the application environment.

The following code example demonstrates an activity that uses active detection to control the start of a workflow:

public class Pollforwork implements activity
Public Processcontext Execute (processcontext context) throws Exception
The ' If work needs to ' is done
Boolean workisready = Lookintodatabaseforwork ();
if (Workisready)
The Polling Action must also load any seed data
((mycontext) context). Setseeddata (Createseeddata ());
Terminate the workflow process for this iteration
((mycontext) context). Setstopentireprocess (True);
return context;

In addition, the Pollrates class contained in the unit tests of the example code provides an example of an active election startup that can be run. The pollrates simulates a repeat check for a drop in the airline's rate.

start a workflow through an ESB event-driven
Ideally, a thread that contains the appropriate seed data can initiate the workflow asynchronously. An example of this is the message received from the Java Message Service queue. A customer listening to a JMS queue or subject will be notified that the processing should start the workflow in the OnMessage () method. Then, you can get the workflow processor bean by using the spring and doactivities (Object seeddata) methods.

Using an ESB, the mechanisms that are actually used to send startup events can be properly detached from the workflow processor. Open Source Project Mule ESB has the benefit of compact and spring integration. Arbitrary transmission mechanisms, such as JMS,JVM, or POP3 mailboxes, can initiate the propagation of events.

continuous operation of workflow
The workflow engine background process should be able to run continuously without interference. There are several options for a single process that is running based on a spring-ready workflow. A simple Java class with the main () method is sufficient to demonstrate the example of a unit test that accompanies this article. A more reliable mechanism for deployment is to embed workflow into some form of Java EE component. Spring is a good way to support the integration of Java EE-compliant Web application archiving or war files. The SAR files supported by the Java Management Attachment (JMX) service archive and the JBoss Application server (for more information, see JBoss Homepage) are more appropriate deployable components, and this more appropriate deployable component can also be used to archive the deployment. In JBoss 4.0, the SAR file has been replaced by the known deployer format.

Example Code
The routine code packaged in ZIP format is best used with Apache maven. You can find the API in the main source code directory Src/java. There are three unit tests in the Src/java directory, including: Simplesequencetestcase,ratedroptestcase and Poolingtestcase. To run all of these tests, type MAVEN test in the command line shell, and then, before compiling and running, MAVEN downloads all the required jar files. The actual XSL transformations will occur in two Tests, and their results are piped out to the console. Type maven Test:ui to pull out the graphical test run, and then select the test you want to run and observe the results of the console.

In this article you have seen the types of workflow processes through design patterns, in which we focused mainly on sequential patterns. By using interfaces, we model the basic workflow components. Implement a sequential workflow by assembling multiple interfaces to spring. Finally, different options for starting and deploying workflows are discussed.

The simple workflow technology presented here is certainly not final and revolutionary. However, using spring to implement a common task like a workflow is a good example of the efficiency achieved by using the IOC container. By reducing the need for adhesive code, Spring keeps object-oriented constraints at the same time reducing the level of problem-oriented operations.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.