我有一个关于弹簧依赖注入的问题。 我需要知道依赖项是否按照XML中声明的顺序注入 没有这样的命令。
示例:
<bean id="empBean" class="com.test.EmployeeBean">
<property name="jdbcTemplate" ref="jdbcTemplate" />
<property name="empAddress" ref="empAddress" />
</bean>
我们能否保证在jdbcTemplate
之前始终empName
初始化?请帮忙
答案 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的顺序,其中顺序很重要。