Issue
I have a number of beans all implementing the same type that are tagged with @Order(x)
where x
is the priority of the bean.
The beans are used by passing a collection of them into another bean as a parameter, however we use SonarQube to statically analyse our code, which suggests you should use a base class unless you are using specific features of the child class.
@Bean
public SomeProcessor someProcessor(Collection<MyBean> beans) {
return new SomeProcessor(beans);
}
If I @Inject
or pass these as a List<>
they retain the order defined by the @Order
annotations.
If I @Inject
or pass these as a Collection<>
they retain the order in which they were created, ignoring the @Order
annotations.
Is this expected behaviour of Spring injection (using Spring Boot 2.4.4)? Or is this something I should raise as a bug?
The following code demonstrates the problem (although in the production code we don't create Strings as Beans, as that would be... unusual):
@Inject
private List<String> stringList;
@Inject
private Collection<String> stringCollection;
@Bean
@Order(1)
public String stringBean1() {
return "BEAN 1";
}
@Bean
@Order(3)
public String stringBean3() {
return "BEAN 3";
}
@Bean
@Order(2)
public String stringBean2() {
return "BEAN 2";
}
@PostConstruct
public void postConstruct() {
log.error("{}", stringCollection);
log.error("{}", stringList);
}
The List
is stored in order 1, 2, 3.
The Collection
is stored in order 1, 3, 2, "ignoring" the @Order
annotation.
Solution
Spring collection based ordering was finally implemented in version 4.0. The improvement is documented in this issue.
The problem you indicated is described in a certain way in this other issue.
But as described there, and as also pointed out by @jwillebrands in his/her answer, a Collection
may or may not be ordered, and Spring will only guarantee the order in lists and arrays:
Your target beans can implement the
org.springframework.core.Ordered
interface or use the@Order
or standard@Priority
annotation if you want items in the array or list to be sorted in a specific order. Otherwise, their order follows the registration order of the corresponding target bean definitions in the container.
Answered By - jccampanero