Issue
I have two modules: module1
and module2
.
module2
depends on module1
.
Configuration in the module1
:
@Configuration
public class ConfigurationInModule1 {
@Bean
public FirstBean firstBean() {
return new FirstBean();
}
@Bean
public SecondBean secondBean(FirstBean firstBean) {
return new SecondBean(firstBean);
}
}
Configuration in the module2
:
@Configuration
public class ConfigurationInModule2 {
@Bean
public SomeBeanForModule2 beanForModule2(FirstBean firstBean) {
return new SomeBeanForModule2(firstBean);
}
}
As you can see both beans secondBean
and beanForModule2
depends on firstBean
.
I need to make sure that when the project is compiled with module2
then beanForModule2
should be initialized before secondBean
. If there is no module2
then secondBean
should be initialized in a standard flow.
Is it possible to configure it in Spring?
P.S. I need to control the order of been initialization. I know that there is a special annotation @DependsOn
which can be used to setup indirect dependency, but in my case I cannot use it on secondBean
because the dependency beanForModule2
is optional and is placed in another module.
Solution
Found the solution by using BeanFactoryPostProcessor
. We need to define our custom BeanFactoryPostProcessor
and setup necessary dependencies there.
Spring won't execute beans initialization before calling postProcessBeanFactory
method.
To solve the above problem we should define our custom BeanFactoryPostProcessor
like this one:
public class JBCDependencyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
BeanDefinition beanDefinition = beanFactory.getBeanDefinition("secondBean");
beanDefinition.setDependsOn("beanForModule2");
}
}
After that we should make a static bean with our BeanFactoryPostProcessor
. Something like this:
@Configuration
public class ConfigurationInModule2 {
@Bean
public static BeanFactoryPostProcessor dependencyBeanFactoryPostProcessor() {
return new JBCDependencyBeanFactoryPostProcessor();
}
@Bean
public SomeBeanForModule2 beanForModule2(FirstBean firstBean) {
return new SomeBeanForModule2(firstBean);
}
}
Spring will search for all beans. Then it will execute postProcessBeanFactory
in our BeanFactoryPostProcessor
. We will make a dependency from secondBean
to beanForModule2
and then spring will call bean initialization by following our dependencies.
P.S. Thanks to @Tarun for sharing the link.
Answered By - Oleksandr