Appreciating Spring | Adding Spring to Plain Java (XML Configuration)

We will try to appreciate the Spring Framework. We will take a Java application and convert it into Java+Spring application.

Objectives

  • How to integrate spring into a java application using xml configuration?
  • What spring will add to a well-designed java application?

Environment

  • Eclipse (Indigo)

Library

If it is your first time with Spring, go to First Time Spring.

( 1 ) Existing Plain Java Application (No Spring Yet!)

The Story:

ShapeFactory is a factory producing shapes, “Circle & Rectangle”.  The production process includes some steps “Tagging & Painting”.

The Design:

The Code:

Shape.java

package com.hmkcode.beans.shapes;

public abstract class Shape {

	private String tag;
	private String color;

	public String getTag() {return tag;}
	public void setTag(String tag) {this.tag = tag;}
	public String getColor() {return color;}
	public void setColor(String color) {this.color = color;}

}

Machine.java

package com.hmkcode.beans.machines;

import com.hmkcode.beans.shapes.Shape;

public abstract class Machine {

	public abstract void start(Shape shape,String value);
}

ShapeFactory.java

package com.hmkcode.beans;

import com.hmkcode.beans.machines.*;
import com.hmkcode.beans.shapes.Circle;
import com.hmkcode.beans.shapes.Rectangle;
import com.hmkcode.beans.shapes.Shape;

public class ShapeFactory {

	String[] shapes = {"circle","rectangle"};
	String[] colors = {"red","blue","yellow","green"};

	private Machine shapeTagger;
	private Machine shapePainter;

	//constructor
	//initiates all machines
	public ShapeFactory(){
		this.shapeTagger = new ShapeTagger();
		this.shapePainter = new ShapePainter();
	}

	//method run
	//runs production process (build -> tag -> paint)
	public void run(){
		//produce 20 shapes
		for(int i = 0 ; i < 20 ; i++){
			Shape shape = build(select(shapes));
			shapeTagger.start(shape,"SF-01-"+i);
			shapePainter.start(shape, select(colors));
		}
	}

	//method build
	//builds the shape based on the passed type of shape
	 private Shape build(String shape){
			if(shape.equals("circle"))
				return new Circle();
			else if(shape.equals("rectangle"))
				return new Rectangle();
			else
				return null;
		}
	//********************************************************
	//method select
	//picks shape type or shape color
	//has nothing to do with spring. forget about it!
	private String select(String[] params){
		double random  = Math.random()*10;

		for(int i = 0 ; i < params.length; i++){
			if(random >= (10/params.length)*i && 
                           random < (10/params.length)*(i+1))
				return params[i];
		}
		return params[params.length-1];
	}

}

( 2 ) Configure the Application for Spring

  • We need to add some library from the downloaded Spring-Framework package
  • Create a new xml configuration file
  • Detailed steps First Time Spring.

( 3 ) XML Configuration (spring-config.xml)

<?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-3.0.xsd">

		<bean id="circle" class="com.hmkcode.beans.shapes.Circle" 
                  scope="prototype" />
		<bean id="rectangle" class="com.hmkcode.beans.shapes.Rectangle" 
                  scope="prototype" />

		<bean id="shapeFactory" class="com.hmkcode.beans.ShapeFactory" >
      		<property name="shapeTagger">
        		<bean class="com.hmkcode.beans.machines.ShapeTagger" />
      		</property> 
      		<property name="shapePainter">
        		<bean class="com.hmkcode.beans.machines.ShapePainter" />
      		</property>   
		</bean>

</beans>

( 4 ) Change the Code (ShapeFactory.java)

  • After adding spring we will make some changes to ShapeFactory.java
//constructor
public ShapeFactory(){}
...
...
...
//method build
//builds the shape based on the passed type of shape	 private Shape build(String shape){
       return (Shape) Main.ctx.getBean(shape);
}

( 5 ) So What?!

  • ShapeFactory has removed all dependencies with children of Shapes and Machines. Now it only knows the parents (Shape & Machine).
  • Now if ShapeFactory needs to add a new or remove an existing shape or machine, nothing need to be changed in the code compared to the old plain java.
  • If the factory is producing 100 different types of shapes using 100 different types of machines, you could imagine how much code would be removed.
  • Of course, this is not what Spring is all about!