Reputation: 3744
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.
Upvotes: 1
Views: 6604
Reputation: 3744
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.
Upvotes: 1
Reputation: 986
Spring takes care of order of bean initialization, So if one bean depends on other then Spring will first initialize dependency Beans then it will initialize dependent Beans.
In your case FirstBean
will always initialize prior than SomeBeanForModule2
without any additional config.
And if Dependency Bean which is FirstBean
in your case is not declared(i.e module1 is not there) then Spring will throw org.springframework.beans.factory.NoSuchBeanDefinitionException
. So module2 cannot initialized without module1.
EDIT:- For Ordering of Bean Initialization, you can use @DependsOn even if Beans are in seperate File.
Just add @import(ConfigurationInModule2.class)
in ConfigurationInModule1 class in your module1.
And use @DependsOn("beanForModule2")
on secondBean.
This will help:- https://stackoverflow.com/a/16297827/4720870
Upvotes: 1