如何从 Spring 中的另一个模块添加 bean 依赖项?

How to add a bean dependency from another module in Spring?

我有两个模块:module1module2
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);
    }
}

如您所见,bean secondBeanbeanForModule2 都依赖于 firstBean。 我需要确保当使用 module2 编译项目时,beanForModule2 应该在 secondBean 之前初始化。如果没有 module2 那么 secondBean 应该在标准流程中初始化 .

是否可以在Spring中配置?

P.S。我需要控制初始化的顺序。我知道有一个特殊的注释 @DependsOn 可以用来设置间接依赖,但在我的例子中我不能在 secondBean 上使用它,因为依赖 beanForModule2 是可选的并且放在另一个模块。

Spring 负责 bean 初始化的顺序,因此如果一个 bean 依赖于另一个 bean,那么 Spring 将首先初始化依赖 Bean,然后它会初始化依赖 Bean。
在您的情况下,FirstBean 将始终在 SomeBeanForModule2 之前初始化,而无需任何其他配置。

并且如果在您的情况下 FirstBean 的依赖 Bean 未声明(即 module1 不存在),则 Spring 将抛出 org.springframework.beans.factory.NoSuchBeanDefinitionException。所以没有module1就不能初始化module2.

编辑:- 对于 Bean 初始化的顺序,即使 Beans 在单独的文件中,您也可以使用 @DependsOn。

只需在您的模块 1 中的 ConfigurationInModule1 class 中添加 @import(ConfigurationInModule2.class)
并在 secondBean 上使用 @DependsOn("beanForModule2")

这将有助于:-

使用 BeanFactoryPostProcessor 找到了解决方案。我们需要定义我们的自定义 BeanFactoryPostProcessor 并在那里设置必要的依赖项。 Spring 在调用 postProcessBeanFactory 方法之前不会执行 beans 初始化。
要解决上述问题,我们应该像这样定义我们的自定义 BeanFactoryPostProcessor

public class JBCDependencyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {

        BeanDefinition beanDefinition = beanFactory.getBeanDefinition("secondBean");
        beanDefinition.setDependsOn("beanForModule2");
    }

}

之后我们应该用 BeanFactoryPostProcessor 创建一个 static bean。像这样:

@Configuration
public class ConfigurationInModule2 {

    @Bean
    public static BeanFactoryPostProcessor dependencyBeanFactoryPostProcessor() {
        return new JBCDependencyBeanFactoryPostProcessor();
    }

    @Bean
    public SomeBeanForModule2 beanForModule2(FirstBean firstBean) {
        return new SomeBeanForModule2(firstBean);
    }
}

Spring 将搜索所有 beans。然后它会在我们的BeanFactoryPostProcessor中执行postProcessBeanFactory。我们将建立从 secondBeanbeanForModule2 的依赖关系,然后 spring 将按照我们的依赖关系调用 bean 初始化。

P.S。感谢@Tarun 分享 link.