I've got a very simple spring boot test application.
It has just a Dog class and the @SpringBootApplication annotated one. I create two beans of Dog and everything runs as expected.
public class Dog {
public String name;
public Dog() {
this("noname");
}
public Dog(String name) {
this.name = name;
}
public String toString() {
return name;
}
}
@SpringBootApplication
public class DemoApplication {
@Autowired
private List<Dog> dogs;
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Bean
CommandLineRunner runner1() {
return args -> {
for (Dog d : dogs) {
System.out.println(d);
}
};
}
@Bean
Dog laika() {
return new Dog("laika");
}
@Bean
Dog lassie() {
return new Dog("lassie");
}
}
Outputs:
laika
lassie
However now I add a @Component annotation to Dog class, expecting that now I'll got three beans of type Dog and that's what it seems to happen if I print all beans with another CommandLineRunner like this one:
@Bean
public CommandLineRunner commandLineRunner(ApplicationContext ctx) {
return args -> {
System.out.println("Let's inspect the beans provided by Spring Boot:");
String[] beanNames = ctx.getBeanDefinitionNames();
Arrays.sort(beanNames);
for (String beanName : beanNames) {
System.out.println(beanName);
}
};
}
Outputs:
Let's inspect the beans provided by Spring Boot:
applicationAvailability
applicationTaskExecutor
commandLineRunner
demoApplication
dog
laika
lassie
lifecycleProcessor
...
Yet, when I use my first CommandLineRunner for printing out the contents of my Dog list, the only output that I get is:
noname
It seems like @Component beans have made the beans declared by @Bean dissapear for collection injection. I observe the same behaviour with any beans, for example if I declare more CommandLineRunners in an independent @Component class, everyone is ran, but when I @Autowire'd them in a list, only the ones declared with @Component are injected.
Nevertheless, I can still use the other Dog beans. For example, if I annotate Laika bean with @Primary, it's the one that will be injected as a method argument, but nothing changes regarding the @Autowire'd collection.