Jay Drummond's – Blog

Posts Tagged ‘commons’

HOW TO – merge Spring Framework and COMMONS Chain ( “Chain of Responsibility” )

Tuesday, March 3rd, 2009

Jakarta Commons Chain project is a gang of four design pattern for “Chain of Responsibility”.

Spring Framework is an open source project that is hosted on Source Forge. It can be summed up as a framework that implements the factory pattern who’s objects are configured with XML documents.

This white paper shows how these two frameworks can be used together. So if you already use Spring and want to add Commons Chain, or if you use Commons Chain and are not quite happy with the supplied catalogue for creating a chain. Then read on.


Goal:

Build some simple examples, step by step, that will allow an understanding of how you can combine Jakarta Commons Chain objects and the Spring Framework. At the completion of these examples you should be able to create Commands and Chains along with your other Spring managed objects.

Prerequisites:

  • This paper assumes a basic knowledge of Java and Eclipse.
  • You should have Eclipse and an Java SDK installed and working.
  • Download the binary distributions of the Spring Framework (the one with dependencies) and Jakarta Commons Chain and unzip them into a directory. This white paper uses the Spring Framework version 1.2.3 and Commons Chain version 1.0.
  • Other jars needed: log4j, Commons Collections, Commons Pool, Commons Dbcp, Commons Lang, and MySql JDBC driver.

Create a project to build examples:

Start your Eclipse IDE and open a workspace where we can create a project to start playing with Spring and Chain frameworks.

Call the project SpringChain as shown in figure 1. Then click next and click "add Folder" to associate a source directory called src with the project. When prompted for the "New Source Folder" type src as the folder name and click OK. Answer yes to the dialog about using a SpringChain/bin directory as the output directory. Your project should look like this now: figure 2. Click Finished.

Add external jar file references to the project. Right click on the
SpringChain
project in the Java perspective. Click properties. In the dialog for the "Properties for SpringChain ", click the "Java Build Path" item and then the libraries tab. Your screen should look like figure 3. Click the "Add External JARS..: button. Add the following jar from the Commons Chain distribution " commons-chain-1.0.jar" Add the following jar from the Spring Framework distribution, spring.jar. Also add the other jar files mentioned in the prerequisites. Your project properties should look something like figure 4. Click OK.

Install the sample code:

Download the samples and unzip into the SpringChain project that you created. Click here to download. Right mouse click on the project and select refresh.

Each sample is contained in it’s own package. In each package you’ll see a class called, RunSample. This class has a main entry point to run the the sample.

Hopefully, you now have a project that looks like the one below:

Project Look

Sample 1 – A simple command:

This sample will show how to create a simple command and execute it after creating it through spring.

First let’s setup Eclipse to debug our Sample.

Open sample1 package by clicking the plus to the left of the package name. Right mouse click on the RunSample source file. From the context menu that pops up, select "Debug As …" then select "Debug". With the "Java Application" item selected in the configurations window, click New. See below:

In the dialog that appears next, check the stop in main option.

Setup log4j logging. Click the Arguments tab. Add the following line to the VM Arguments.

-Dlog4j.configuration=file:///${project_loc}/log4j.xml

See below.

Click debug to step through the sample.

Now back to the sample code. The following files are found in this sample:

HelloWorld – a class that implements a Command interface. This will be created with the spring framework.

RunSample – a class that loads the Spring configuration file.

beans.xml – the Spring configuration file that defines the beans that are going to be created in the sample.

 

Beans.xml defines the Command as follows:

<?xml version="1.0" encoding="UTF-8"?>
       <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

       <beans>
 <bean id="testBean" class="com.drummondsoftware.sample1.HelloWorld" singleton="true">
 </bean>
</beans>

As you can see there’s nothing complex about creating HelloWorld. Just define the bead id and the class.

The HelloWorld class is simply going to print the message "Hello World" when the command executes.

public class HelloWorld implements Command {
 String message = "Hello World"; 
 /* (non-Javadoc)
   * @see org.apache.commons.chain.Command#execute(org.apache.commons.chain.Context)
   */
   public boolean execute(Context arg0) throws Exception {
   System.out.println(message);
   return true;
   }
 }

The RunSample class will initialize the spring framework and then pass control the an exec method where the spring factory creates a Commons Command and executes it.

public class RunSample {
 private XmlBeanFactory factory;

 /**
 * here's where the fun starts
 *
 */
 private void exec() {
   Command cmd = (Command) getFactory().getBean("testBean");

   try {
    cmd.execute(null);
   } catch (Exception e) {
    e.printStackTrace();
   }
 }

 public static void main(String[] args) {
   XmlBeanFactory factory = new XmlBeanFactory(new FileSystemResource("src/com/drummondsoftware/sample1/beans.xml"));

   RunSample loadSome = new RunSample();
   loadSome.setFactory(factory);
   loadSome.exec();
 }

 

Sample 2 – Chains:

This sample will show how to put commands together into chains. The chains also get created from Spring.

Start by setting up Eclipse for debugging this sample just like was done in Sample 1.

 

In the Beans.xml we define 4 commands that will be chained together.

Command 1 – 3 are simple commands. They simply log the classname to the logger.

Command 4 is a command that creates another command or chain and runs it. The chainName is set by Spring when the command is created.

Now let’s examine a chain definition. Lines 14 through 21 of Beans.xml define test Chain object. This is shown below.

The class in this definition is a Commons Chain class. It’s the ChainBase class that holds a list of commands to be run. The list is specified in a Spring constructor definition. This simply makes reference to the commands we defined earlier. So when testChain runs it will call command1 followed by command2.

testChain2 – is similar to testChain.

testChain3 – runs a command and then runs testChain and testChain2. This shows that chains can be added to a chain.

testChain4 – runs command4 which is the indirect chain runner.

RunSample shown below simply loads the spring configuration file and run the chains in order:

 

Sample 3 – Contexts and datasource:

This sample will show how to add context class creation to the Spring beans definitions. I also have add a datasource to the mix to show how easy it is to use other Spring objects in your commands.

Start by setting up Eclipse for debugging this sample just like was done in Sample 1.

In the Beans.xml we define the same 4 commands that will be chained together. Command 2 gets a datasource.

Two contexts are defined. Both of these are the Common Chain base class implementations. The spring framework loads the context object up with keyword value pairs contained in a Map.

The Chains defined in the Beans.xml file are unchanged from the last sample.

The RunSample class initializes the Spring factory. It also loads a property file that configures the datasource connection settings.

Control is passed to the exec method where now the context objects are created and passed into the chains when they are run.

Step through this sample and watch the trace output.

Hopefully this helps you get a quick start into use of Commons Chains and and Spring framework together.

 
 
Table of Contents
   
   

Home Page
Products
Services
blog
News
about us
Company Information
Links
Contact Us


 

Drummond Software Group
Massillon, Ohio
330-412-4090