Reading Notes for Spring 3 Core Components Tutorial Part II (Chapter 11 to Chapter 13)
This is a reading note from Spring Framework 3.1 Tutorial pdf, created by tutorialspoint. This pdf contains information for Spring 3 Core Basics, which is very useful for understanding defination and practive in Spring programming.
Note: All tips that is written by book will has a sign near it. All code example in this post comes from book.
This note includes Chapter 11 to Chapter 13 in tutorial.
Chapter 11: Spring Dependency Injection
Dependency Injection (or Wiring) helps in gluing individual application classes together and same time keeping them independent.
There are two types of DI: Constructor-Based DI and Setter-Based DI:
Constructor-based DI is accomplished when the container invokes a class constructor with a number of arguments, each representing a dependency on other class.
Setter-based DI is accomplished by the container calling setter methods on your beans after invoking a no-argument constructor or no-argument static factory method to instantiate your bean.
It is a good practive to use constructor arguments formandatory dependenciesand setter foroption dependencies Constructor-Based Dependency Injection
public TextEditor(SpellCheck spellChecker){ //A SpellCheck will be instantiated first, based on bean setting
System.out.println("Construcor of Text Editor");
this.spellChecker = spellChecker;
}
public void spellCheck(){
spellChecker.checkSpelling();
}
}
//Constructor for spellChecker
public class spellChecker{
//Construcor that doesn't take any argument
System.out.prinln("Construcor of Spell Checker")'
}
public void checkSpelling(){
System.out.println("Checking Spelling !");
}
//Main Class
public class Main{
pulic void static main(String[] args){
ApplicationContext context = new ClassPathXmlApplicationContext('bean.xml');
TextEditor te = (TextEditor) context.getBean('textEditor');
te.spellCheck();
//Output: Contrutor of Spell Checker
//Output: Contrutor of Text Editor
//Output: Check Spelling !
}
}
Consructor Arguments Resolution
Ambiguity can happen when a constroctor takes more than one parameters. Spring make sure the order of constrctor-arg in bean xml file defines the order of parameters taken by construcor in java file.
If you have type attribute in xml file, Spring can use Type-Matching to check these parameters.
Important: If you try to pass reference in <constructor-args>, use ref attribute. If you try to pass value in <constructor-args>, use value attribute.
The best way is to use index attribute in xml file. Example:
1
2
3
4
5
6
7
8
<beans>
<beanid="foo"class="x.y.Foo">
<constructor-argindex="0"ref="bar"/><!--part by reference-->
<constroctor-argindex="1"type="java.lang.String"value="Test"/><!--pass by value. Specify type here-->
</bean>
<beanid="bar"class="x.y.Bar"/>
</beans>
1
2
3
4
5
6
7
//Class for Foo
publicclassFoo{
publicFoo(Bar bar, Stirng t){
//Here bar call its own constructor
//t have value "test", which is defined in xml file
//This class use default-construcor (i.e, no self-defined constructor)
publicclassTextEditor{
private SpellChekcer spellChecker;
//getter to ruturn a spellChecker
public SpellChecker getSpellChecker{
return spellChecker;
}
//setter
public ovid setSpellChecker(SepellChekcer spellChecker){
System.out.println("setSpellChecker!");
this.spellChecker = spellChecker;
}
publicvoidspellCheck(){
spellChecker.checkSpelling();
}
}
//Main Class
publicclassMain{
publicstaticvoidmain(String[] args){
ApplicationContext context = new ClassPathXmlApplicationContext('beans.xml');
(TextEditor) te = (TextEditor) context.getBeans('textEditor');
te.spellCheck();
}
//Output: spellChecker constructor!
//setSpellChecker!
//checkSpelling!
}
The difference in xml file between Constructor DI and Setter-Base DI is: <construcotr-args> is used by Constructor DI; <property> is used by Setter-Based DI.
Similar as Constructor DI, if you want to pass reference in xml file, use ref attribute. If you want to pass value in xml file, use value attribute.
XML Configuration using P-Namespace
p-namespace is easier for a bean with many setter methods.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!--old way-->
<beanid="test"class="com.sample.test">
<propertyname="name"value="John Smith"/>
<propertyname="spouse"ref="jane"/>
</bean>
<beanid="jane"class="com.sample.Person">
<propertyname="name"value="John Smith"/>
</bean>
<!--new way-->
<beanid="test"class="com.sample.test"
p:name="John Smith"
p:spouse-ref = "jane"
> <!--you don't need -value attribute if you pass by value-->
</bean>
<beanid="jane"class="com.sample.Person"
p:name="John Smith"
>
</bean>
Chapter 12: Spring Injecting Inner Beans
The code above can be transferred to inner bean. Just like inner class in Java, inner bean is the bean defined inside <construcor-args> or <property>.