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.