'Simply about Spring' post illustration

Simply about Spring

This article is devoted to very popular framework Spring. It’s very necessary theme for beginners in Java, because Spring is widespread technology.
First of all let's consider wiring - dynamical assembling of separated beans, most important part of Spring framework technology. It's important to keep in mind, that a good understanding of fundamental things is a irreplaceable skill for really cool programmer.

Spring framework works with module based applications, so let's take a brief look at simple programm which peform ariphmetic operations.

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
public class CalcExample {

    public CalcExample() {
    } 

    public static void main(String[] args) {
        CalcExample calc = new CalcExample(); calc.execute(args);
    } 

    private void printResult(String result) {
        System.out.println(result);
    } 

    private long operate(long number1, long number2) {
        return number1 + number2;
    }

    private String getOpsName() {
        return " plus ";
    }

    public void execute(String [] args) {
        long number1 = Long.parseLong(argument[0]);
        long number2 = Long.parseLong(argument[1]);
        printResult("The result of " + number1 + getOpsName() + number2 +
        " is " + operate(number1, number2) + "!");
    }
}

Nice code for beginners, but we have to obtain program contains
several modules, which can be changed in simple way. It's very useful method of software development - separating code into parts you can change couple of them or add following to rules complying rules described in interfaces (or just implement it).

So we need interface in out program, let's do it:

1
2
3
4
public interface Operation {
    long operate(long op1, long op2);
    String getOpsName();
}

Addition

1
2
3
4
5
6
7
8
9
10
11
12
public class OpAdd implements Operation {
    public OpAdd() {
    }

    public String getOpsName() {
        return " plus "; 
    }

    public long operate(long number1, long number2) {
        return number1 + number2; 
    } 
}

Mutiply

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
public class OpMultiply implements Operation {
    public OpMultiply() {
    }

    public String getOpsName() {
        return " times ";
    }

    public long operate(long number1, long number2) {
        return number1 * number2;
    }
}

public class CalcExampleBeans {
    private Operation ops = new OpAdd();
    private ResultWriter wtr = new ScreenWriter();
    
    public static void main(String[] args) {
        CalcExampleBeans calc = new CalcExampleBeans();
        calc.execute(args);
    }

    public void execute(String [] args) {
        long number1 = Long.parseLong(argument[0]);
        long number2 = Long.parseLong(argument[1]);
        wtr.showResult("The result of " + number1 + ops.getOpsName() + number2 + 
        " is " + ops.operate(number1, number2) + "!");
    }
}

Well, we have two separated beans OpAdd and OpMultiply, they both implement interface Operation. Everything is clean but, what will we do, if we need to change bean during program execution?
Here Spring can help us. Dynamically connecting beans via build.XML file, Spring undertook to create container for connecting components with their usage.
The beauty of this solution is that CalculateSpring does not works with instances of Operation or ResultWriter, but delegates this task to Spring container. Spring container, in turn, reads configuration XML file and calls the bean descriptor.

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
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class CalculateSpring {
    private Operation ops; private ResultWriter wtr;

    public void setOps(Operation ops) {
        this.ops = ops;
    }

    public void setWriter(ResultWriter writer) {
        this.wtr = writer;
    } 

    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        BeanFactory factory = (BeanFactory) context;
        CalculateSpring calc =(CalculateSpring) factory.getBean("opsbean");
        calc.execute(args);
    }

    public void execute(String [] args) {
        long number1 = Long.parseLong(argument[0]);
        long number2 = Long.parseLong(argument[1]);
        wtr.showResult("The result of " + number1 + ops.getOpsName() + number2 + " is " + ops.operate(number1, number2) + "!");
    }
}

So we create context, factory and via factory we can get bean. ApplicationContext in Spring is a type BeanFactory. BeanFactory takes ability of access to initialized JavaBeans, connected and managed by Spring contailner. Although there are other classes in the BeanFactory Spring, ApplicationContext class is much more commonly used because it provides us with several valuable features - the inclusion of support for internationalization, resource loading, integration with external hierarchies contest and much more.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?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-2.0.xsd">

  <bean id="screen" class="com.wrox.begspring.ScreenWriter" />

  <bean id="multiply" class="com.wrox.begspring.OpMultiply" />

  <bean id="add" class="com.wrox.begspring.OpAdd" />

  <bean id="opsbean" class="com.wrox.begspring.CalculateSpring">
    <property name="ops" ref="multiply" /> <property name="writer" ref="screen"/>
  </bean>

</beans>

The article will be continued next week, we'll talk about Inversion of Control (IoS) in Spring.

If you're looking for a developer or considering starting a new project,
we are always ready to help!