Spring有兩種不同的容器:BeanFactory和ApplicationContext。
BeanFactory提供基本的IoC支持。ApplicationContext是基于BeanFactory之上的,提供了應用程序框架服務,例如從properties文件中讀取信息等。
Spring提供了BeanFactory和ApplicationContext的多個實現。
2.1.1 BeanFactory介紹
BeanFactory由org.springframework.beans.factory.BeanFactory接口定義。BeanFactory是工廠模式(Factory pattern)的實現,因此BeanFactory負責創建和分發bean。BeanFactory不僅僅是創建和分發bean,它同時還負責在實例化bean時創建bean之間的聯系。BeanFactory還可以參與到bean的生命周期中,它可以調用對象的初始化函數和析構函數(自行定義的函數,在xml中指定為析構函數)。
Spring中最常用的是XmlBeanFactory。
假設Greeting接口定義了方法sayHello();GreetingImpl實現了Greeting接口。XML文件定義如下:
<?xml version = "1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTDBEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="greetingService"
class="GreetingImpl">
<property name="greeting">
<value>Hello</value>
</property>
</bean>
</beans>
/***interface Greeting********/
public interface Greeting{
public void sayHello();
}
/****class GreetingImpl*********/
public class GreetingImpl implements Greeting{
public GreetingImpl () {
}
private String greeting;
public void sayHello(){
System.out.println(greeting);
}
public void setGreeting(String helloWord){
greeting=helloWord;
}
}
/****class ExecutableApp***********/
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.FileSystemResource;
public class ExecutableApp {
public ExecutableApp () {
}
public static void main(String args[]){
FileSystemResource fileSystemResource = new FileSystemResource("configuration.xml");
BeanFactory factory = new XmlBeanFactory(fileSystemResource);
Greeting personA = (Greeting)factory.getBean("greetingService");
personA.sayHello();
}
}
注:上述程序中紅色的部分在Spring-framework-1.2.5運行通過。和Spring in action中的不同。
該程序的運行結果是:Hello。
BeanFactory factory = new XmlBeanFactory(fileSystemResource);
該語句從configuration.xml文件中讀取bean的定義,但是并不立即實例化bean,直到需要使用這些bean的時候,才會實例化他們。在上面的例子中,實例化是在調用factory.getBean()的時候進行的。例如,我們將GreetingImpl修改成為
public class GreetingImpl implements Greeting{
public GreetingImpl () {
System.out.println("Instance GreetingImpl object");
}
……
}
將ExecutableApp修改為
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.FileSystemResource;
public class ExecutableApp {
public ExecutableApp () {
}
public static void main(String args[]){
System.out.println(“Before load xml file”);
FileSystemResource fileSystemResource = new FileSystemResource("configuration.xml");
BeanFactory factory = new XmlBeanFactory(fileSystemResource);
System.out.println(“After load xml file”);
Greeting personA = (Greeting)factory.getBean("greetingService");
personA.sayHello();
}
}
運行結果為:
Before load xml file
After load xml file
Instance GreetingImpl object
Hello
也就是說,在裝載bean的定義的時候,BeanFactory并沒有實例化bean。
“需要使用這些bean的時候”并不是只包括調用getBean方法的時候。在上面的例子中,我們加入一個新的接口及其實現:
public interface Person {
public String getName();
}
public class MrSmith implements Person{
private String name="Mr Smith";
public MrSmith() {
System.out.println("Instance MrSmith object");
}
public String getName(){
return name;
}
}
修改configuration.xml文件和GreetingImpl類:
public class GreetingImpl implements Greeting{
public GreetingImpl () {
System.out.println("Instance GreetingImpl object");
}
private String greeting;
Person who;
public void sayHello(){
System.out.println(greeting + “,” + who.getName());
}
public void setGreeting(String helloWord){
greeting=helloWord;
}
public void setWho(Person who){
this.who=who;
}
}
<?xml version = "1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTDBEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="person" class="MrSmith"/>
<bean id="greetingService"
class="GreetingImpl">
<property name="greeting">
<value>Hello</value>
</property>
<property name="who”>
<ref bean="person"/>
</property>
</bean>
</beans>
在運行ExecutableApp時,輸出的結果是:
Before load xml file
After load xml file
Instance GreetingImpl object
Instance MrSmith object
Hello,Mr Smith
首先實例化的是GreetingImpl類,然后實例化了MrSmith類。我們在ExecutableApp中并沒有調用getBean來生成MrSmith類,但是在xml文件的greetingService bean的定義中,我們應用了person bean,因此也生成了MrSmith類的實例。