介面 BeanFactory 和 ApplicationContext 都是用來從容器中獲取 Spring beans 的,但是,他們二者有很大不同
我看到過很多問 BeanFactory 和 ApplicationContext 不同點的問題,考慮到這,我應該使用前者還是後者從 Spring 容器中獲取 beans 呢?請向下看
什麼是 Spring Bean
這是一個非常簡單而又很複雜的問題,通常來說,Spring beans 就是被 Spring 容器所管理的 Java 物件,來看一個簡單的例子
package com.zoltanraffai;
public class HelloWorld {
private String message;
public void setMessage(String message){
this.message = message;
}
public void getMessage(){
System.out.println("My Message : " + message);
}
}
在基於 XML 的配置中, beans.xml 為 Spring 容器管理 bean 提供後設資料
什麼是 Spring 容器
Spring 容器負責例項化,配置和裝配 Spring beans,下面來看如何為 IoC 容器配置我們的 HelloWorld POJO
<?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 = "helloWorld" class = "com.zoltanraffai.HelloWorld">
<property name = "message" value = "Hello World!"/>
</bean>
</beans>
現在,它已經被 Spring 容器管理了,接下來的問題是:我們怎樣獲取它?
BeanFactory 和 ApplicationContext 的不同點
BeanFactory 介面
這是一個用來訪問 Spring 容器的 root 介面,要訪問 Spring 容器,我們將使用 Spring 依賴注入功能,使用 BeanFactory 介面和它的子介面
特性:
- Bean 的例項化/串聯
通常情況,BeanFactory 的實現是使用懶載入的方式,這意味著 beans 只有在我們通過 getBean() 方法直接呼叫它們時才進行例項化
實現 BeanFactory 最常用的 API 是 XMLBeanFactory
這裡是如何通過 BeanFactory 獲取一個 bean 的例子:
package com.zoltanraffai;
import org.springframework.core.io.ClassPathResource;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.xml.XmlBeanFactory;
public class HelloWorldApp{
public static void main(String[] args) {
XmlBeanFactory factory = new XmlBeanFactory (new ClassPathResource("beans.xml"));
HelloWorld obj = (HelloWorld) factory.getBean("helloWorld");
obj.getMessage();
}
}
ApplicationContext 介面
ApplicationContext 是 Spring 應用程式中的中央介面,用於嚮應用程式提供配置資訊
它繼承了 BeanFactory 介面,所以 ApplicationContext 包含 BeanFactory 的所有功能以及更多功能!它的主要功能是支援大型的業務應用的建立
特性:
- Bean instantiation/wiring
- Bean 的例項化/串聯
- 自動的 BeanPostProcessor 註冊
- 自動的 BeanFactoryPostProcessor 註冊
- 方便的 MessageSource 訪問(i18n)
- ApplicationEvent 的釋出
與 BeanFactory 懶載入的方式不同,它是預載入,所以,每一個 bean 都在 ApplicationContext 啟動之後例項化
這裡是 ApplicationContext 的使用例子:
package com.zoltanraffai;
import org.springframework.core.io.ClassPathResource;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.xml.XmlBeanFactory;
public class HelloWorldApp{
public static void main(String[] args) {
ApplicationContext context=new ClassPathXmlApplicationContext("beans.xml");
HelloWorld obj = (HelloWorld) context.getBean("helloWorld");
obj.getMessage();
}
}
總結
ApplicationContext 包含 BeanFactory 的所有特性,通常推薦使用前者。但是也有一些限制情形,比如移動應用記憶體消耗比較嚴苛,在那些情景中,使用更輕量級的 BeanFactory 是更合理的。然而,在大多數企業級的應用中,ApplicationContext 是你的首選。
靈魂追問
- 如何使用 BeanPostProcessor 和 BeanFactoryPostProcessor ?
- 你瞭解 Spring Bean 的生命週期嗎?瞭解了這些對與 bean 的使用將有非常大的幫助.
歡迎持續關注,後續會出一系列文章進行 Spring 知識點解釋與串聯,輕鬆搞定面試那點事,以及在工作中充分利用 Spring 的特性
翻譯自:Difference Between BeanFactory and ApplicationContext in Spring