I have following @Configuration
class, in which I am declaring a @Bean that depends on an @Autowired
list of beans. However, this list is not complete when I am accessing to it. All @Bean
definitions been executed, except the one defined in the same class.
@Configuration
public class MyConfig {
@Autowired
List<RequiredBean> requiredBeans;
@Bean(name="ProblemHere")
public CustomObject customObject() {
log.info(requiredBeans.size()); // 1 (debugging, I can see is the one defined in "AnotherConfigClass")
}
@Bean(name="reqBeanInsideClass")
public RequiredBean reqBean() {
// this method does not get executed
return new RequiredBean();
}
}
Having other classes like;
@Configuration
public class AnotherConfigClass {
@Bean(name="ThisOneGetsExecuted")
public RequiredBean reqBean() {
// this gets executed, and therefore, added to the list
return new RequiredBean();
}
}
Probably, the easiest solution would be to add @DependsOn("reqBeanInsideClass").
However:
- I wonder why it works for all
@Bean
s defined in different classes, but not in this one. - I'm not really sure that's exactly like that, and I'm afraid later on, another
@Bean
does not get executed I guess the correct approach should be something like
@DependsOn(List<RequiredBean>) // Obviously this does not work
How should I solve this?
Update
I have copied the exact same class twice, in order to see what would happen, so now I have also:
@Configuration
public class MyConfig2 {
@Autowired
List<RequiredBean> requiredBeans;
@Bean(name="ProblemHere2")
public CustomObject customObject() {
log.info(requiredBeans.size());
}
@Bean(name="reqBeanInsideClass2")
public RequiredBean reqBean() {
// this method does not get executed
return new RequiredBean();
}
}
Amazingly, by doing this, both @Beans
methods (ProblemHere
& ProblemHere2
) are called before both reqBeanInsideClass
and reqBeanInsideClass2
methods.
For some reason I guess, Springboot is able to recognize @Beans
required for a class as long as they are defined in another class.
- Does this sound logic to anyone?
Can you not utilize the array input for
@DependsOn
rather than passing singular value, since it acceptsString[]
? That would wait for all the beans that are explicitly declared in the array before initializing, though has to be defined manually.@Autowired
list of beans will be same as a single bean of same type, it will contain all beans with that type or with that superclass via springs injection, the problem is the ordering of bean initialization is not controlled properly,@DependsOn
with array bean input should resolve this!Or
You can make
CustomObject
bean@Lazy
, so it will be initialized only when it is used within the code after initialization is done. The bean must not be used within another non-lazy bean I think. Just call some logic where an@Autowired
CustomObject
is used, it should instantiate the bean at that moment, where the list will contain all possibleRequiredBean
s