在Spring官方文档的描述中,如果一个Bean A依赖另外一个Bean B,那么在IOC容器初始化两个Bean时,首先会初始化被依赖的Bean B,再初始化依赖Bean A.
我们来看实例:
假如有两个Bean,一个是Bean我们命名为car,另外一个命名为carrey, carrey依赖car。
car.java
/**
* @Comment
* @Author Ron
* @date 2016年9月23日 上午9:59:53
*/
public class car {
public car(){
System.out.println("I'm a car.");
}
}
carrey.java
/**
* @Comment
* @Author Ron
* @date 2016年9月23日 上午10:01:40
*/
public class carrey {
private car car;
public carrey() {
System.out.println("I'm a carrey car.");
}
public car getCar() {
return car;
}
public void setCar(car car) {
this.car = car;
}
}
测试类main.java
/**
* @Comment
* @Author Ron
* @date 2016年9月23日 上午9:47:12
*/
public class Main {
public static void main(String[] args) {
ApplicationContext apc = new ClassPathXmlApplicationContext("springXML/test.xml");
carrey carrey = apc.getBean("carrey",carrey.class);
}
}
首先,我们不使用depends-on属性,按照通常情况下的配置方法来配置两个bean的依赖关系
1、将被依赖的Bean car配置到依赖Bean carrey之前
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean class="learn.car" id="car"></bean>
<bean class="learn.carrey" id="carrey">
<property name="car" ref="car" />
</bean>
</beans>
运行结果
I'm a car.
I'm a carrey car.
2、将被依赖的Bean car配置到依赖Bean carrey之后
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean class="learn.carrey" id="carrey">
<property name="car" ref="car" />
</bean>
<bean class="learn.car" id="car"></bean>
</beans>
运行结果
I'm a carrey car.
I'm a car.
为什么会出现以上不同的运行结果呢???官方文档不是说,如果一个Bean A依赖另外一个Bean B,那么在IOC容器初始化两个Bean时,首先会初始化被依赖的Bean B,再初始化依赖Bean A吗?后来查了一下,原因是IOC容器在初始化单例Bean时,优先按照Bean的配置顺序初始化,如果两个相互依赖的Bean在初始化时,依赖Bean A的初始化之前需要强制先初始化被依赖的Bean B,这时就需要用到depends-on属性了。
对于以下两种配置,IOC容器首先都会初始化car,再初始化 carrey
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean class="learn.car" id="car"></bean>
<bean class="learn.carrey" id="carrey" depends-on="car">
<property name="car" ref="car" />
</bean>
</beans>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean class="learn.carrey" id="carrey" depends-on="car">
<property name="car" ref="car" />
</bean>
<bean class="learn.car" id="car"></bean>
</beans>
运行结果:
I'm a car.
I'm a carrey car.
3、使用depends-on的好处
在一些特殊情况下,Bean初始化时需要调用一些静态的初始化程序,在特殊情况下,这些被调用的静态初始化程序的值是通过被依赖的Bean设置的,比如我们以上的所举的car和carrey,carrey依赖car,在carrey初始化时我们需要打印引擎名称(Engine Name),但是引擎名称我们是在car中设置的,同时引擎名称是引擎类(Engine)中的一个静态属性engname
Engine.java
/**
* @Comment
* @Author Ron
* @date 2016年9月23日 上午11:08:29
*/
public class Engine {
private static String engname;
public static String getEngname() {
return engname;
}
public static void setEngname(String engname) {
Engine.engname = engname;
}
}
car.java
/**
* @Comment
* @Author Ron
* @date 2016年9月23日 上午9:59:53
*/
public class car {
public car(){
System.out.println("I'm a car.");
Engine.setEngname("Ron");
}
}
carrey.java
/**
* @Comment
* @Author Ron
* @date 2016年9月23日 上午10:01:40
*/
public class carrey {
private car car;
public carrey() {
System.out.println("I'm a carrey car.");
System.out.println("Engine Name-->"+Engine.getEngname());
}
public car getCar() {
return car;
}
public void setCar(car car) {
this.car = car;
}
}
如果不使用depends-on
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean class="learn.carrey" id="carrey">
<property name="car" ref="car" />
</bean>
<bean class="learn.car" id="car"></bean>
</beans>
运行结果:
I'm a carrey car.
Engine Name-->null
I'm a car.
使用depends-on
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean class="learn.carrey" id="carrey" depends-on="car">
<property name="car" ref="car" />
</bean>
<bean class="learn.car" id="car"></bean>
</beans>
运行结果:
I'm a car.
I'm a carrey car.
Engine Name-->Ron