Spring中depends-on属性

本文介绍如何在Spring框架中使用depends-on属性来控制Bean的初始化顺序。通过示例展示了当需要在一个Bean初始化前先初始化另一个Bean时,如何配置XML来实现这一需求。
有时候在创建某个Bean之前,需要先创建另一个Bean,这时可以使用depends-on属性。
public class Shared {

private static String value;

public static String getValue() {
return value;
}

public static void setValue(String value) {
Shared.value = value;
}

}

public class User {

public User() {
System.out.println("User initialized");
Shared.setValue("Set value in User Constructor!");
}

}

public class Goods {

public Goods() {
System.out.println("Goods initialized");
}

public String toString() {
return "Shared.getValue() = " + Shared.getValue();
}

}

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

<bean id="user" class="User"/>

<bean id="goods" class="Goods"/>

</beans>

//测试
public static void main(String[] args) {
XmlBeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("beans-config.xml"));
Goods goods = (Goods)beanFactory.getBean("goods");
System.out.println(goods);
}
/**Output:
Goods initialized
Shared.getValue() = [color=red]null[/color]
*/
从输出看到,Shared.value属性没有赋值,而给Shared.value属性赋值需要实例化User类,所以我们实例化Goods之前要先实例化User。
修改bean定义文件
<bean id="goods" class="Goods" depends-on="user"/>

再次运行测试
/**Output:
User initialized
Goods initialized
Shared.getValue() = [color=red]Set value in User Constructor![/color]
*/
可以看到,在实例化Goods之前先实例化了User。
<think>好的,我需要回答用户关于Spring中mbd.getDependsOn()方法的作用以及depends-on属性的问题。首先,我需要回忆Spring Bean的生命周期和配置相关的内容。 根据用户提供的引用,特别是引用[4],里面提到了RootBeanDefinition的scope属性和单例Bean的创建过程。虽然引用没有直接提到depends-on,但我知道depends-on用于指定Bean之间的依赖关系,确保某个Bean在另一个Bean之前初始化。 接下来,我需要确认mbd.getDependsOn()方法的来源。mbd应该是AbstractBeanDefinition的实例,而getDependsOn()方法应该返回该Bean所依赖的其他Bean的名称数组。这样,Spring在初始化当前Bean之前会先初始化这些依赖的Beandepends-on属性XML配置中常见,比如<bean id="A" depends-on="B"/>,这样A会在B之后初始化。这个属性解决了Bean之间没有直接引用但需要顺序初始化的情况。例如,数据库配置Bean可能需要在日志Bean初始化之后加载。 需要区分depends-on和其他依赖注入方式。@Autowired或构造器注入隐式地创建了依赖关系,而depends-on是显式的,适用于没有直接引用但需要顺序的情况。 还要考虑循环依赖的问题,如果depends-on形成循环,Spring会抛出异常。这点需要提到。 最后,结合用户提供的引用,特别是引用[1]中提到的AbstractBeanDefinition,可以说明mbd作为Bean定义的一部分,存储了这些依赖信息。而引用[4]中的getSingleton和createBean过程可能涉及到处理这些依赖关系,确保正确的初始化顺序。 总结下来,回答需要涵盖depends-on的作用、使用场景、与隐式依赖的区别、配置方法及循环依赖的问题,并适当引用用户提供的资料来支持解释。</think>### Spring Bean 的 `mbd.getDependsOn()` 方法及 `depends-on` 属性详解 #### 1. `depends-on` 属性的核心作用 在 Spring 中,`depends-on` 属性用于 **显式声明 Bean 之间的初始化顺序依赖关系**。当一个 Bean(假设为 Bean A)依赖另一个 BeanBean B)时,即使两者没有直接的属性引用或方法调用,也能确保 Bean B 在 Bean A 之前完成初始化[^1]。 例如,在 XML 配置中: ```xml <bean id="beanA" class="com.example.BeanA" depends-on="beanB"/> <bean id="beanB" class="com.example.BeanB"/> ``` 此时,Spring 会先初始化 `beanB`,再初始化 `beanA`。 --- #### 2. `mbd.getDependsOn()` 方法的作用 `mbd` 是 `AbstractBeanDefinition` 的实例(如 `RootBeanDefinition`),`getDependsOn()` 方法返回当前 Bean 所依赖的其他 Bean 名称的数组。这些依赖关系会在 Bean 初始化前被处理,确保依赖的 Bean 优先完成初始化[^4]。 例如,在 Bean 创建过程中: ```java String[] dependsOn = mbd.getDependsOn(); if (dependsOn != null) { for (String dep : dependsOn) { // 确保依赖的 Bean 先注册并初始化 registerDependentBean(dep, beanName); getBean(dep); // 触发依赖 Bean 的初始化 } } ``` 这一逻辑保证了依赖关系的强制执行[^3][^4]。 --- #### 3. 典型应用场景 - **隐式依赖管理** 当 Bean A 需要某个资源(如文件、配置)由 Bean B 提前初始化完成时,即使两者无直接关联,也可通过 `depends-on` 确保顺序。 - **解决非直接引用的初始化顺序** 例如,数据库连接池 Bean 可能依赖日志配置 Bean,但前者并未直接调用后者的方法。 --- #### 4. 与隐式依赖注入的区别 | 类型 | 实现方式 | 适用场景 | |---------------|------------------------|------------------------------| | `depends-on` | 显式声明依赖顺序 | 无直接引用但需初始化顺序控制 | | `@Autowired` | 通过属性/构造器隐式注入| 存在直接引用关系时 | --- #### 5. 配置方式示例 - **XML 配置** ```xml <bean id="serviceA" class="com.example.ServiceA" depends-on="daoB,utilC"/> ``` - **注解配置** 通过 `@DependsOn` 注解: ```java @Component @DependsOn({"databaseConfig", "securityConfig"}) public class AppService { ... } ``` --- #### 6. 循环依赖问题 如果 Bean A 依赖 Bean B,而 Bean B 又反向依赖 Bean A,Spring 会抛出 `BeanCurrentlyInCreationException`。需通过设计调整(如懒加载、接口分离)避免此类问题。 --- ### 相关问题 1. **如何通过注解方式实现类似 `depends-on` 的效果?** (答案:使用 `@DependsOn` 注解) 2. **`depends-on` 与 Bean 的 `init-method` 执行顺序有何关系?** (答案:`depends-on` 控制 Bean 初始化的触发顺序,而 `init-method` 在 Bean 实例化后按顺序执行) 3. **Spring 如何处理多个层级的 `depends-on` 依赖?** (答案:通过依赖关系拓扑排序,确保所有依赖链有序) : AbstractBeanDefinitionBeanDefinition 接口的抽象实现类,提供了一些通用的属性和方法,用于描述 Spring Bean 的定义。 : 关于 registerDependentBean 方法,我们在之前的文章中有过解释。 : 如果 RootBeanDefinition 的 scope 属性是单例的,则调用 getSingleton 创建单例 Bean
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值