Java-29 深入浅出 Spring - IoC 基础 启动IoC容器的方式 Java方式与Web(XML、配置)方式

0 阅读6分钟

Spring IoC 容器入门:BeanFactory vs ApplicationContext 区别与启动方式详解(2026)

TL;DR

  • 场景:Spring 初学者搭建企业级项目时,常混淆 IoC 容器顶层接口与具体实现,不知道该选 BeanFactory 还是 ApplicationContext,以及 Java / Web 环境下的容器启动方式
  • 结论:ApplicationContext 是 BeanFactory 的子接口,功能更完整(国际化、事件、AOP、资源加载),是企业开发首选;Java 环境用 ClassPathXmlApplicationContext / AnnotationConfigApplicationContext,Web 环境用 ContextLoaderListener
  • 产出:1 张接口继承图 + 1 张功能对比表 + 2 段 web.xml 配置(XML 方式与配置类方式)

Java-29 深入浅出 Spring - IoC 基础 启动IoC容器的方式 Java方式与Web(XML、配置)方式

版本矩阵

功能状态说明
BeanFactory 顶层接口定义✅ 已验证org.springframework.beans.factory.BeanFactory 是 Spring IoC 容器最顶层接口
ApplicationContext 子接口✅ 已验证继承自 BeanFactory,提供企业级扩展能力
ClassPathXmlApplicationContext✅ 已验证从类路径加载 XML 配置,JavaSE 环境常用
FileSystemXmlApplicationContext✅ 已验证从磁盘路径加载 XML 配置文件
AnnotationConfigApplicationContext✅ 已验证基于 Java 配置类启动 Spring 容器
ContextLoaderListener✅ 已验证Web 环境启动 Spring 容器的标准监听器
Spring 5.1.12.RELEASE 版本✅ 已验证5.1.x 稳定线版本,2019 年末发布,5.1.13 为 2020-01-14 最终维护版

IoC 基础

IoC 基础:beans.xml 与 BeanFactory 容器,以及纯 XML / XML+注解 / 纯注解三种配置模式对比

BeanFactory 和 ApplicationContext 区别

BeanFactory 是 Spring 框架中 IoC 容器的顶层接口,定义了 IoC 容器最基础的功能规范,例如 Bean 的获取、管理和依赖注入等。

ApplicationContext 是 BeanFactory 的子接口,因此它具备 BeanFactory 的全部能力。同时,ApplicationContext 在此基础上扩展了更多企业级开发常用功能,例如国际化、资源访问、事件发布、AOP 集成等。

简单理解:

BeanFactory 更偏底层,是 Spring IoC 容器的基础接口;ApplicationContext 更偏应用层,是实际开发中更常用的高级容器接口。

BeanFactory 与 ApplicationContext 的接口继承关系图:ApplicationContext 继承自 BeanFactory,常见实现类有 ClassPathXmlApplicationContext、FileSystemXmlApplicationContext、AnnotationConfigApplicationContext

BeanFactory

  • Spring IoC 容器的核心基础接口。
  • 提供最基本的 Bean 管理能力。
  • 默认采用延迟初始化,也就是在真正获取 Bean 时才创建对象。
  • 更轻量,适合资源受限或底层框架扩展场景。
  • 常见实现类:DefaultListableBeanFactory。

ApplicationContext

  • BeanFactory 的子接口,功能更完整。
  • 容器启动时通常会预先创建单例 Bean。
  • 支持国际化、事件发布、资源加载、AOP 等高级功能。
  • 更适合企业级应用开发。
  • 常见实现类:ClassPathXmlApplicationContext、FileSystemXmlApplicationContext、AnnotationConfigApplicationContext 等。

BeanFactory 与 ApplicationContext 功能对比表:涵盖 Bean 初始化时机、国际化、事件、依赖注入、Bean 后处理器、AOP、资源访问、生命周期管理 8 个维度

BeanFactory 场景

BeanFactory 通常用于比较底层或资源受限的场景。

例如:

  • 框架底层扩展。
  • 测试环境。
  • 对容器功能要求较少的简单场景。
  • 需要尽量延迟创建 Bean 的场景。

在日常业务开发中,一般不会直接使用 BeanFactory。

ApplicationContext 场景

ApplicationContext 是 Spring 应用中最常用的 IoC 容器。

它适用于大多数企业级项目,能够支持:

  • XML 配置。
  • Java 配置类。
  • 注解扫描。
  • 国际化。
  • 事件监听。
  • AOP。
  • Web 环境集成。

因此,在实际开发中,通常优先使用 ApplicationContext。

项目准备

拷贝项目

这里我们将上一节的项目拷贝一份,后续内容会在原有项目基础上继续调整。

这样做的好处是可以保留上一节的代码,同时避免本节改动影响之前的示例。

添加依赖

在上一节依赖的基础上,继续加入下面这些 Spring 相关依赖:

<!-- Spring -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.1.12.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>5.1.12.RELEASE</version>
</dependency>
<dependency>
    <groupId>javax.annotation</groupId>
    <artifactId>javax.annotation-api</artifactId>
    <version>1.3.2</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aop</artifactId>
    <version>5.1.12.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.8.13</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>5.1.12.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-tx</artifactId>
    <version>5.1.12.RELEASE</version>
</dependency>

这些依赖中:

  • spring-context:提供 ApplicationContext、注解配置、资源加载等核心能力。
  • spring-web:提供 Web 环境下启动 Spring 容器的支持。
  • javax.annotation-api:提供 @PostConstruct、@PreDestroy 等注解。
  • spring-aop 和 aspectjweaver:用于后续 AOP 相关功能。
  • spring-jdbc 和 spring-tx:用于后续数据库操作和事务控制。

对应截图如下所示:

Maven pom.xml 依赖配置截图:包含 tomcat-embed-core 9.0.39、lombok 1.18.22,以及 spring-context 5.1.12.RELEASE 等 Spring 系列依赖

启动 IoC 容器

Spring IoC 容器可以在 Java 环境中启动,也可以在 Web 环境中启动。不同环境下,启动方式略有区别。

Java 环境

在普通 Java 程序中,常见的容器启动方式有以下几种:

  • ClassPathXmlApplicationContext:从类路径下加载 XML 配置文件,常用于学习和传统 XML 项目。
  • FileSystemXmlApplicationContext:从磁盘路径加载 XML 配置文件。
  • AnnotationConfigApplicationContext:基于 Java 配置类启动 Spring 容器,常用于纯注解开发。

例如,如果使用 XML 配置文件,可以通过 ClassPathXmlApplicationContext 启动容器;如果使用配置类,则可以通过 AnnotationConfigApplicationContext 启动容器。

Web 环境

在 Web 项目中,Spring 容器通常不是由 main 方法手动启动,而是交给 Web 容器启动。

常见做法是在 web.xml 中配置 ContextLoaderListener。Web 项目启动时,监听器会自动创建 Spring IoC 容器。

XML 方式

如果使用 XML 配置方式启动 Spring 容器,可以修改 webapp/WEB-INF 下的 web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
</web-app>

上面配置中,ContextLoaderListener 会在 Web 项目启动时初始化 Spring 容器。

如果没有额外指定配置文件位置,Spring 默认会去查找 /WEB-INF/applicationContext.xml

对应的截图如下所示:

web.xml XML 方式配置截图:通过 ContextLoaderListener 监听器启动 Spring 容器,Spring 默认查找 /WEB-INF/applicationContext.xml

配置类 方式

如果项目使用 Java 配置类,也可以通过 web.xml 指定容器类型和配置类位置:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">
    <context-param>
        <param-name>contextClass</param-name>
        <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
    </context-param>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>wzk.SpringConfig</param-value>
    </context-param>
    <!--使⽤监听器启动Spring的IOC容器-->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
</web-app>

这里需要注意两个参数:

  • contextClass:指定使用 AnnotationConfigWebApplicationContext,也就是基于注解和配置类的 Web 容器。
  • contextConfigLocation:指定 Spring 配置类的全限定类名,这里是 wzk.SpringConfig

项目启动时,ContextLoaderListener 会读取这些配置,并根据指定的配置类创建 Spring IoC 容器。

对应的截图如下所示:

web.xml 配置类方式截图:通过 contextClass 指定 AnnotationConfigWebApplicationContext,contextConfigLocation 指向 wzk.SpringConfig 配置类


错误速查卡

症状根因定位修复
启动报错 FileNotFoundException: /WEB-INF/applicationContext.xmlWeb 环境下只配了 ContextLoaderListener,未指定配置文件位置,Spring 走默认路径检查 web.xml 是否缺少 contextConfigLocation 参数<context-param> 中显式指定 applicationContext.xml 路径,或改用配置类方式
启动报错 ClassNotFoundException: AnnotationConfigWebApplicationContextweb.xml 中 contextClass 指定了注解容器,但 pom.xml 缺少 spring-web 依赖检查 pom.xml 中是否引入 spring-web加入 org.springframework:spring-web:5.1.12.RELEASE 依赖
Bean 在获取时才报错 NoSuchBeanDefinitionException使用 BeanFactory 但未注册 Bean,或包扫描路径配置错误检查 beans.xml<context:component-scan>@ComponentScan 注解路径修正扫描包路径,确保目标类在扫描范围内
@PostConstruct / @PreDestroy 注解不生效缺少 javax.annotation-api 依赖,或被 Spring 的 CommonAnnotationBeanPostProcessor 排除检查 pom.xml 是否引入 javax.annotation-api 1.3.2添加 javax.annotation:javax.annotation-api:1.3.2 依赖
容器启动后单例 Bean 已被提前创建,影响启动速度默认走 ApplicationContext 的预加载行为确认容器类型,BeanFactory 才是延迟加载若必须延迟加载,显式使用 DefaultListableBeanFactory
Spring 5.1.12.RELEASE 报 CVE 安全漏洞该版本已是 5.1.x 旧版本线,5.1.13 为最终维护版,5.1.x 已 EOL查看 pom.xml 中的 spring-* 版本号升级到 Spring 5.3.x 或 6.x(配合 Spring Boot 2.7+ / 3.x)

作者:武子康的个人博客