当前位置: 首页 > news >正文

Spring容器进化论:从BeanFactory到ApplicationContext

🧱 一、先说结论:你应该用哪个?

除非有特殊需求,否则永远使用 ApplicationContext,而不是直接使用 BeanFactory

这是 Spring 官方明确推荐的实践。

  • BeanFactory 是底层基础。
  • ApplicationContext 是在 BeanFactory 基础上构建的高级容器,功能更全、更智能、更适合实际开发。

🔍 二、什么是 BeanFactory?

1. 核心定义

BeanFactory 是 Spring IoC 容器的最基础接口,提供了:

  • 创建 Bean 实例(bean instantiation)
  • 依赖注入(wiring / dependency injection)

但它只是一个“最小内核”,不包含很多高级功能。

2. 特点

  • 轻量级、可定制性强。
  • 不会自动处理生命周期回调或扩展点(比如后处理器)。
  • 更适合框架集成或需要精细控制 bean 加载过程的场景。

举个比喻:

💡 BeanFactory 就像一辆汽车的发动机 —— 动力核心,但没有方向盘、空调、倒车雷达这些便利设施。


🏗️ 三、什么是 ApplicationContext?

ApplicationContext 接口继承了 BeanFactory,所以它天然具备所有 BeanFactory 的能力,并在此基础上增加了许多企业级功能。

你可以把它看作一个“完整版 Spring 容器”。

它比 BeanFactory 多了哪些关键能力?

功能是否支持
自动注册 BeanPostProcessor✅ 是
自动注册 BeanFactoryPostProcessor✅ 是
国际化消息支持 (MessageSource)✅ 是
发布应用事件 (ApplicationEvent)✅ 是
生命周期管理(如初始化/销毁方法调用)✅ 是

⚠️ 注意:如果你只用 DefaultListableBeanFactoryBeanFactory 的实现类),上面这些功能默认不会生效!你需要手动注册和触发。


🤔 四、为什么 ApplicationContext 更好?—— 以 BeanPostProcessor 为例

场景:你想使用 @Autowired

@Autowired 注解的功能是由一个叫 AutowiredAnnotationBeanPostProcessor 的组件实现的。

❌ 如果你只用了 DefaultListableBeanFactory
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
factory.addBeanDefinition(...); // 手动注册一些 bean// ❗问题来了:@Autowired 不会起作用!
// 因为没有任何人来扫描并处理这个注解

👉 解决办法:必须手动添加后处理器:

factory.addBeanPostProcessor(new AutowiredAnnotationBeanPostProcessor());
✅ 而如果你用的是 ApplicationContext(例如 AnnotationConfigApplicationContext
ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
// 此时 @Autowired 已经可以正常工作!

因为 Spring 在启动时自动检测并注册了所有必要的后处理器,包括:

  • AutowiredAnnotationBeanPostProcessor
  • CommonAnnotationBeanPostProcessor
  • ConfigurationPropertiesBindingPostProcessor 等等

🎯 这就是“自动 BeanPostProcessor 注册”的意义所在!


🔩 五、BeanFactoryPostProcessor 又是什么?

这类处理器用于修改 Bean 的元数据定义(即 BeanDefinition),而不是操作 bean 实例本身。

典型例子:PropertySourcesPlaceholderConfigurer

它的作用是把 ${...} 占位符替换成真实值(比如从 jdbc.properties 文件读取数据库密码)。

❌ 在纯 BeanFactory 中要这么写:

DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
reader.loadBeanDefinitions(new FileSystemResource("beans.xml"));// 手动创建配置器
PropertySourcesPlaceholderConfigurer cfg = new PropertySourcesPlaceholderConfigurer();
cfg.setLocation(new FileSystemResource("jdbc.properties"));// ❗必须手动调用 postProcessBeanFactory 方法才能生效
cfg.postProcessBeanFactory(factory);

✅ 而在 ApplicationContext 中:

AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.register(PropertyConfig.class); // 包含 @PropertySource 或 PropertySourcesPlaceholderConfigurer
ctx.refresh(); // refresh 期间自动执行 postProcessBeanFactory

👉 所有这一切都被封装好了,开发者无需关心细节。


📊 六、表格再解读:Feature Matrix

功能BeanFactoryApplicationContext
Bean 实例化与装配
集成的生命周期管理
自动注册 BeanPostProcessor
自动注册 BeanFactoryPostProcessor
方便访问 MessageSource(国际化)
内置事件发布机制(ApplicationEvent)

📌 总结一句话:

ApplicationContext = BeanFactory + 自动化 + 企业级服务


🛠️ 七、什么时候该用 BeanFactory?

虽然官方建议优先用 ApplicationContext,但在以下情况可以考虑 BeanFactory

  1. 嵌入式系统或资源受限环境:想最小化内存占用。
  2. 自定义容器逻辑:你需要完全掌控 bean 的加载顺序和处理流程。
  3. 框架开发:你在做一个基于 Spring 的新框架,需要底层接入。
  4. 测试或调试特定行为:排除高级功能干扰,观察原始行为。

但对于绝大多数应用开发(Web 应用、微服务、批处理等),都应该选择 ApplicationContext


🌱 八、常见的 ApplicationContext 实现类

类名用途
ClassPathXmlApplicationContext从 classpath 下的 XML 配置文件加载
FileSystemXmlApplicationContext从文件系统的 XML 文件加载
AnnotationConfigApplicationContext使用 Java 注解配置类(推荐)
GenericApplicationContext最灵活的基础类,可用于编程式注册 bean

👉 推荐使用:

new AnnotationConfigApplicationContext(MyConfig.class);

它是现代 Spring 开发的标准入口。


✅ 九、总结:如何理解这段话?

我们可以把原文浓缩成几个关键思想:

原文要点白话解释
BeanFactory 是 IoC 的基础所有容器都基于它,但它太原始
ApplicationContext 包含 BeanFactory 的全部功能是“超集”,更强更方便
ApplicationContext 自动注册各种后处理器@Autowired, @Value, AOP 等开箱即用
若仅用 DefaultListableBeanFactory,需手动注册后处理器很麻烦,容易出错
推荐使用 ApplicationContext,特别是 AnnotationConfigApplicationContext现代 Spring 的标准做法

🧩 补充:图示理解层级关系

        BeanFactory (基础接口)↑ListableBeanFactory↑
DefaultListableBeanFactory (核心实现)↑AbstractApplicationContext↑GenericApplicationContext↑
AnnotationConfigApplicationContext↑your application

所有的高级容器最终都是建立在 DefaultListableBeanFactory 之上的。


✅ 最终建议

日常开发中,请始终使用 ApplicationContext
首选 AnnotationConfigApplicationContext + Java Config 模式
不要手动 new DefaultListableBeanFactory 来做主容器(除非你知道自己在做什么)


如果你想动手试试,这里是一个完整的例子:

示例:使用 AnnotationConfigApplicationContext(推荐方式)

@Configuration
@ComponentScan("com.example.service")
@PropertySource("classpath:app.properties")
public class AppConfig {@Beanpublic MyService myService() {return new MyServiceImpl();}
}// 启动
public class Main {public static void main(String[] args) {ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);MyService service = ctx.getBean(MyService.class);service.doSomething(); // @Autowired、@Value、生命周期等均已生效}
}

在这个例子中,一切自动化完成:扫描组件、处理注解、替换占位符、发布事件……

这就是 ApplicationContext 的强大之处。


如有具体代码或场景想分析,欢迎继续提问!

http://www.dtcms.com/a/528360.html

相关文章:

  • 20.7 零样本多模态实战:CLIP模型如何让ChatPPT图像识别吞吐量飙升406%
  • 可以做平面设计兼职的网站佛山市网站建设分站哪家好
  • win11系统下配置c++机器学习库mlpack
  • [人工智能-大模型-72]:模型层技术 - 模型训练六大步:①数据预处理 - 基本功能与对应的基本组成函数
  • java基础-13 : 双列集合(Map)
  • 【十年后台管理系统】Redis的使用
  • SSM框架-MyBatis2
  • 深入理解JVM垃圾回收机制:从原理到实践
  • Spring的后处理器
  • 本地佛山顺德网站设计深圳市宝安区西乡街道
  • 监控 Linux 系统上的内存使用情况
  • 湖北省住房与建设厅网站高品质的网站开发
  • 智慧校园建设方案-6PPT(32页)
  • Spring的@Cacheable取缓存默认实现
  • MySQL-TrinityCore异步连接池的学习(七)
  • 2020应该建设什么网站建网站的论坛
  • 华为OD机考双机位A卷 - Excel单元格数值统计 (C++ Python JAVA JS GO)
  • SpringBoot集成Elasticsearch | Elasticsearch 7.x专属HLRC(High Level Rest Client)
  • 广东省住房城乡建设厅门户网站免费下载手机app
  • 信创入门指南:一文掌握信息技术应用创新的核心要点
  • 基于鸿蒙UniProton的物联网边缘计算:架构设计与实现方案
  • 基于Swin Transformer的脑血管疾病中风影像诊断系统研究
  • 宝安第一网站东莞关键词优化软件
  • 篮球论坛|基于SprinBoot+vue的篮球论坛系统(源码+数据库+文档)
  • SQL 进阶:触发器、存储过程
  • ansible快速准备redis集群环境
  • 公司网站制作效果长沙网站制造
  • 数据结构之堆
  • 【Linux学习笔记】日志器与线程池设计
  • 【Linux系统编程】编辑器vim