【发布时间】:2012-12-07 20:04:00
【问题描述】:
是否可以指定实例化 bean 的顺序?即我希望在其他 bean 之前实例化特定的 bean,就像启动顺序一样。
我正在使用 Spring 3.2 和基于注释的声明方法。
【问题讨论】:
-
在我的实践中,实例化顺序等于 xml 配置文件中的顺序。但也可能有例外..
是否可以指定实例化 bean 的顺序?即我希望在其他 bean 之前实例化特定的 bean,就像启动顺序一样。
我正在使用 Spring 3.2 和基于注释的声明方法。
【问题讨论】:
如果 bean A 通过定义 <property/>、@Autowired 或 <constructor-arg/> 依赖于 bean B,则顺序由 Spring 容器强制和固定。这里没问题。
但是,如果您想强制执行未通过显式依赖项表达的特定 bean 创建顺序,请随意使用:
<bean id="A" depends-on="B"/>
<bean id="B"/>
或更好(带有注释,也适用于@Bean Java 配置):
@Service
@DependsOn("B")
public class A {}
甚至更好...不要使用它。这些结构是一种代码味道,通常表明您的组件之间存在一些令人讨厌的无形依赖关系。
【讨论】:
同意 Tomasz 提供的答案。如果您知道 bean A 依赖于 bean B,那么这是正确的方法。
有时您的逻辑应该在所有 bean 实例化之前执行。在这种情况下,您可以使用BeanFactoryPostProcessor。 Spring 首先创建并执行 BeanFactoryPostProcessors,然后只创建和执行所有其他 bean。同时,如果您的 BeanFactoryPostProcessor 依赖于某个 bean A,您可以使用属性或构造函数注入。在这种情况下,Spring 将首先创建 bean A,然后是您的 BeanFactoryPostProcessor,调用 BeanFactoryPostProcessor,然后仅实例化上下文中的所有其他 bean。
【讨论】:
您可以在 bean 上使用 Ordered 接口来定义相对于其他 bean 的排序。
【讨论】:
另外,如果你像emamedov所说的那样使用BeanFactoryPostProcessor,可以实现Ordered接口来控制BeanFactoryPostProcessor的实例顺序。
【讨论】: