BeanFactory 是 Spring 的基礎容器接口,ApplicationContext 繼承並擴展了它,提供企業級開發所需的豐富特性。本文從接口體系、核心功能差異、資源加載方式、Bean 載入策略、典型實現類、Web 應用啟動六個維度全面對比。
BeanFactory (org.springframework.beans.factory)
↑
ApplicationContext (org.springframework.context)
↑
ConfigurableApplicationContext
↑
├── ClassPathXmlApplicationContext
├── FileSystemXmlApplicationContext
└── XmlWebApplicationContext (Web 環境專用)
| 特性 | BeanFactory | ApplicationContext |
|---|---|---|
| Bean 管理 | 基本 DI、生命周期 | 繼承所有,預設單例預實例化 |
| 國際化 (i18n) | 不支持 | MessageSource 內建支持 |
| 資源訪問 | 不支持 | ResourceLoader 統一訪問 classpath/文件/URL |
| 事件發布 | 不支持 | ApplicationEventPublisher 觀察者模式 |
| 多配置加載 | 不支持 | 父子上下文層級結構 |
| AOP 集成 | 手動掛載 | 自動識別 @Aspect、代理創建 |
| Web 集成 | 無 | XmlWebApplicationContext、ContextLoaderListener |
// BeanFactory (XmlBeanFactory) 僅支持 Resource 參數
Resource res = new ClassPathResource("applicationContext.xml");
BeanFactory bf = new XmlBeanFactory(res);
// ApplicationContext 支持多種前綴
ApplicationContext ctx1 = new ClassPathXmlApplicationContext("applicationContext.xml"); // classpath:
ApplicationContext ctx2 = new ClassPathXmlApplicationContext("classpath:applicationContext.xml"); // 顯式 classpath:
ApplicationContext ctx3 = new ClassPathXmlApplicationContext("file:E:/conf/applicationContext.xml"); // 文件系統絕對路徑
ApplicationContext ctx4 = new FileSystemXmlApplicationContext("src/applicationContext.xml"); // 相對項目根目錄
ApplicationContext ctx5 = new FileSystemXmlApplicationContext("E:/conf/applicationContext.xml"); // 文件系統絕對路徑
// Web 環境專用
XmlWebApplicationContext wac = new XmlWebApplicationContext();
wac.setServletContext(servletContext);
wac.setConfigLocation("/WEB-INF/spring/*.xml");
wac.refresh();
getBean() 時實例化單例 Bean生產環境強烈建議使用 ApplicationContext,避免首次請求時的初始化延遲與潛在錯誤。
<!-- web.xml 傳統配置 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
ContextLoaderListener 啟動時創建根 ApplicationContext(父上下文),DispatcherServlet 創建子上下文,形成父子層級,共享服務層 Bean、隔離控制器 Bean。
// 非 Web 環境
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
MyBean bean = ctx.getBean("myBean", MyBean.class);
// Web 環境 (Controller/Service 中注入最佳,否則)
WebApplicationContext wac = WebApplicationContextUtils
.getWebApplicationContext(servletContext);
MyBean bean = wac.getBean("myBean", MyBean.class);
AnnotationConfigApplicationContext 或 ClassPathXmlApplicationContextXmlWebApplicationContext (XML) 或 AnnotationConfigWebApplicationContext (Java Config)DefaultListableBeanFactory 手動註冊SpringApplication.run() 內部構建 AnnotationConfigServletWebServerApplicationContext總結:ApplicationContext 是 BeanFactory 的**企業級超集**,除非有極特殊約束,實際開發中**始終優先使用 ApplicationContext 及其子類**。