Skip to content

使用 depends-on

如果一个 Bean 是另一个 Bean 的依赖项,这通常意味着一个 Bean 被设置为另一个 Bean 的属性。通常,你可以通过基于 XML 的元数据中的 <ref/> 元素或通过自动装配来实现。

然而,有时 Bean 之间的依赖关系并不那么直接。例如,当类中的静态初始化器需要被触发时,比如用于数据库驱动程序的注册。depends-on 属性或 @DependsOn 注解可以显式强制在初始化使用此元素的 Bean 之前,先初始化一个或多个 Bean。

以下示例使用 depends-on 属性来表达对单个 Bean 的依赖:

xml
<bean id="beanOne" class="ExampleBean" depends-on="manager"/>
<bean id="manager" class="ManagerBean" />

要表达对多个 Bean 的依赖,请提供 Bean 名称列表作为 depends-on 属性的值(逗号、空格和分号都是有效的分隔符):

xml
<bean id="beanOne" class="ExampleBean" depends-on="manager,accountDao">
	<property name="manager" ref="manager" />
</bean>

<bean id="manager" class="ManagerBean" />
<bean id="accountDao" class="x.y.jdbc.JdbcAccountDao" />

注意depends-on 属性既可以指定初始化时的依赖关系,而且在仅针对单例 (Singleton) Bean 的情况下,还可以指定相应的销毁时依赖关系。与给定 Bean 定义了 depends-on 关系的依赖 Bean 会被先销毁,优于给定 Bean 本身被销毁。因此,depends-on 也可以控制关闭顺序。


补充教学 —— 掌握隐式的执行顺序

1. 什么时候该用 depends-on 绝大多数情况下,你不需要它。只要你的 A 对象里有一个 private B b; 字段并用了 @Autowired 或 XML 的 <ref>,Spring 就能自动推断出“必须先创建 B,再创建 A”。 只有在 没有直接引用关系 但有 先后顺序要求 时才使用它。

2. 典型应用场景

  • 数据库初始化:Bean A 负责初始化数据库表结构,Bean B 是数据源。虽然 B 不直接调用 A,但 B 启动前 A 必须完成。
  • 配置环境:某个 Bean 负责向 System.setProperty() 写入关键环境参数,其他 Bean 需要读取这些参数。
  • 缓存与资源管理:确保数据库连接池在缓存管理器关闭之前保持可用。

3. “谁先死”的逻辑:销毁顺序 这是一个容易被忽视的细节。depends-on="B" 对 Bean A 的含义是:

  • 出生时:B 必须比 A 先出生。
  • 死亡时:A 必须比 B 先死亡。
  • 逻辑:既然 A 依赖于 B 提供的某种环境或资源,那么在 A 还没关闭前,B 必须一直坚守岗位。

4. 避免滥用 如果你在 A 里面已经通过构造函数或 Setter 注入了 B,再加一个 depends-on="B" 就相当于“脱裤子放屁” —— 既冗余又增加了维护负担。Spring 的依赖图 (Dependency Graph) 已经足够智能处理直接引用。

Based on Spring Framework.