我有两个模块:module1
和module2
。
module2
依赖于module1
。
module1
中的配置:
@Configuration
public class ConfigurationInModule1 {
@Bean
public FirstBean firstBean() {
return new FirstBean();
}
@Bean
public SecondBean secondBean(FirstBean firstBean) {
return new SecondBean(firstBean);
}
}
module2
中的配置:
@Configuration
public class ConfigurationInModule2 {
@Bean
public SomeBeanForModule2 beanForModule2(FirstBean firstBean) {
return new SomeBeanForModule2(firstBean);
}
}
你可以看到豆子secondBean
和beanForModule2
取决于firstBean
。我需要确保当项目使用module2
编译时,beanForModule2
应该在secondBean
之前初始化。如果没有module2
,那么secondBean
应该在标准流程中初始化。
是否可以在Spring中配置它?
附:我需要控制初始化的顺序。我知道有一个特殊的注释@DependsOn
可用于设置间接依赖,但在我的情况下,我不能在secondBean
上使用它,因为依赖beanForModule2
是可选的,并放在另一个模块中。
Spring负责bean初始化的顺序,因此如果一个bean依赖于其他bean,那么Spring将首先初始化依赖Bean,然后它将初始化依赖的Beans。
在你的情况下,FirstBean
将始终在SomeBeanForModule2
之前初始化,而无需任何额外的配置。
如果在你的情况下是FirstBean
的Dependency Bean没有声明(即module1不存在)那么Spring将抛出org.springframework.beans.factory.NoSuchBeanDefinitionException
。因此,如果没有module1,module2就无法初始化。
编辑: - 对于Bean初始化的排序,即使Beans位于单独的文件中,也可以使用@DependsOn。
只需在module1中的ConfigurationInModule1类中添加@import(ConfigurationInModule2.class)
即可。
并在secondBean上使用@DependsOn("beanForModule2")
。
使用BeanFactoryPostProcessor
找到解决方案。我们需要定义我们的自定义BeanFactoryPostProcessor
并在那里设置必要的依赖项。在调用postProcessBeanFactory
方法之前,Spring不会执行bean初始化。
要解决上述问题,我们应该像这样定义我们的自定义BeanFactoryPostProcessor
:
public class JBCDependencyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
BeanDefinition beanDefinition = beanFactory.getBeanDefinition("secondBean");
beanDefinition.setDependsOn("beanForModule2");
}
}
之后我们应该用我们的BeanFactoryPostProcessor
制作一个静态bean。像这样的东西:
@Configuration
public class ConfigurationInModule2 {
@Bean
public static BeanFactoryPostProcessor dependencyBeanFactoryPostProcessor() {
return new JBCDependencyBeanFactoryPostProcessor();
}
@Bean
public SomeBeanForModule2 beanForModule2(FirstBean firstBean) {
return new SomeBeanForModule2(firstBean);
}
}
Spring将搜索所有bean。然后它将在我们的postProcessBeanFactory
中执行BeanFactoryPostProcessor
。我们将依赖secondBean
到beanForModule2
,然后spring将通过跟随我们的依赖来调用bean初始化。
附:感谢@Tarun分享链接。