什么是春季的订单依赖注入?

时间:2017-07-20 09:26:19

标签: java spring dependency-injection

我有一个关于弹簧依赖注入的问题。  我需要知道依赖项是否按照XML中声明的顺序注入  没有这样的命令。

示例:

<bean id="empBean" class="com.test.EmployeeBean">
      <property name="jdbcTemplate" ref="jdbcTemplate" />
       <property name="empAddress" ref="empAddress" />
    </bean>

我们能否保证在jdbcTemplate之前始终empName初始化?请帮忙

2 个答案:

答案 0 :(得分:4)

你不能保证这些将以任何特定的顺序注入,你应该设计你的bean,这无关紧要 - 这很容易实现。

所以这个类是坏代码,因为bean创建后的状态会因Spring发生的顺序而有所不同:

public class BadClass {
    private String foo = "";
    private String foobar = "";

    public void setFoo(String foo) {
        this.foo = foo;
    }

    public void setBar(String bar) {
        this.foobar = foo + bar;
    }

    public String toString() {
        return foobar;
    }
}

由于:

 BadClass c = new BadClass(); 
 c.setFoo("foo");
 c.setBar("bar"); 
 return c.toString()` 

...返回"foobar"

 BadClass c = new BadClass(); 
 c.setBar("bar"); 
 c.setFoo("foo");
 return c.toString()` 

...返回"bar"

许多人认为使用构造函数注入是最佳实践,在这种情况下,所有注入都将在构造函数的一次调用中发生。

public class BetterClass {
    private String foo = "";
    private String foobar = "";

    public BetterClass(String foo, String bar) {
        this.foo = foo;
        this.foobar = foo + bar;
    }

    public String toString() {
        return foobar;
    }
}

答案 1 :(得分:2)

Spring容器将遍历依赖项的 DAG (有向非循环图),并将尽可能多地验证配置,而不创建bean的实例。这里的例外是 singleton-scoped pre-instanciated bean,它们是在创建容器时创建的。您可以通过将lazy-init="true"属性添加到bean定义来修改此行为。

只有在代码中请求bean时,它才会实际创建,并首先创建所有依赖项(如果需要,还会创建它们的依赖项)遍历依赖项图( DAG )所有通往最深层的依赖关系。

另一种情况是稍后使用完全相同的名称定义bean。这些覆盖了之前定义的bean - 所以如果你有一些bean的模拟,只需在核心应用程序bean加载后定义它。

当某些依赖项不明确时,您还可以添加属性depends-on="list,of,comma,separated,beanIDs"以添加属性@Order(N)以指导容器。

使用带注释的类进行配置时,您还可以添加N,其中较低的test获得更高优先级的顺序,主要用于影响添加到集合中的bean的顺序,其中顺序很重要。