Spring 使用 ref 和 depends-on 属性的使用

在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

 

posted @ 2016-09-23 11:22  无名小红  阅读(460)  评论(0编辑  收藏  举报