Spring Bean 是由 IoC 容器托管的对象,XML 中通过 声明,支持构造器/Setter 注入、作用域、生命周期方法等,推荐显式配置而非 autowire。

Spring Bean 就是被 Spring IoC 容器创建、管理并组装的对象——它不是你用 new 手动 new 出来的,而是由容器按需实例化、注入依赖、执行生命周期回调的“托管对象”。
XML 是 Spring 最早也最直观的 Bean 定义方式,虽然现在主流用注解或 Java Config,但维护老项目、对接特定命名空间(如 tx:、aop:)时,XML 仍不可替代。
怎么在 XML 中声明一个基础 Bean?
最简形式只需 标签 + id 和 class 属性:
Spring 会调用该类的无参构造器创建实例。注意:class 是字符串,类名改了不会报编译错误,重构时容易漏掉,这是 XML 的典型隐患。
-
id必须唯一,且不能含空格/特殊字符;推荐用小写字母+驼峰(如userDao) - 不写
id也可,Spring 会自动生成类似userService#0的名称,但不便于引用 - 如果类没有无参构造器,必须配合
或c:命名空间显式传参
如何给 Bean 注入依赖?构造器 vs Setter
两种主流方式:构造器注入(强依赖)、Setter 注入(可选/可变依赖)。别混用,否则语义混乱。
构造器注入(推荐):
Setter 注入(需对应 setXxx() 方法):
- 用
ref引用另一个 Bean;用value注入字面量(如字符串、数字) - 构造器注入能保证依赖不为 null,适合核心协作对象;Setter 更灵活,适合后期动态替换
- 避免在同一个 Bean 上既用构造器又用 Setter 注入同一依赖——Spring 不报错,但逻辑难维护
自动装配(autowire)能省事,但慎用
XML 支持 autowire 属性,比如 autowire="byType",让 Spring 自动找匹配类型的 Bean 注入。听起来方便,实际问题不少:
- 多个同类型 Bean 时会抛
NoUniqueBeanDefinitionException - 类型模糊(如接口有多个实现)时行为不可控,调试困难
- 隐藏依赖关系,阅读 XML 无法一眼看出谁依赖谁
- 团队协作中易引发意外覆盖(尤其多人同时改同一配置文件)
建议:只在简单原型或临时脚本中尝试,生产环境坚持显式注入( 或 )。
作用域、初始化与销毁这些细节别漏掉
默认是 singleton(整个容器只有一个实例),但有些场景需要每次获取都新建:
若 Bean 需要资源初始化或清理,用 init-method 和 destroy-method:
-
scope写错(比如 Web 项目误用request却没配 Spring MVC 上下文)会导致IllegalStateException -
init-method方法必须无参、public、非静态;否则启动时报BeanCreationException - 全局默认值可用
,但建议按需显式配置,避免隐式约定
真正麻烦的从来不是写几行 XML,而是当十几个 相互引用、作用域混搭、初始化顺序交错时,异常堆栈里根本看不出哪条链断了。这时候,宁可多写两行 ref,也别赌 autowire 的运气。










