Skip to content

Map injection doesn't honor @Order #34688

@quaff

Description

@quaff
import static org.assertj.core.api.Assertions.assertThat;

import java.util.List;
import java.util.Map;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;

@SpringJUnitConfig
class OrderConsistencyTests {

	@Test
	void test(@Autowired Map<String, Service> serviceMap,
			@Autowired List<Service> serviceList) {
		assertThat(serviceMap.values()).containsExactlyElementsOf(serviceList);
	}

	static class Service implements BeanNameAware {

		private String beanName;

		@Override
		public void setBeanName(String name) {
			this.beanName = name;
		}

		@Override
		public String toString() {
			return beanName;
		}
	}

	@Configuration
	static class Config {

		@Bean
		Service service1() {
			return new Service();
		}

		@Bean
		@Order(Ordered.LOWEST_PRECEDENCE - 1)
		Service service2() {
			return new Service();
		}

		@Bean
		@Order(Ordered.LOWEST_PRECEDENCE - 2)
		Service service3() {
			return new Service();
		}
		
		@Bean
		@Order(Ordered.LOWEST_PRECEDENCE - 3)
		Service service4() {
			return new Service();
		}
		
		@Bean
		@Order(Ordered.LOWEST_PRECEDENCE - 4)
		Service service0() {
			return new Service();
		}

	}

}
org.opentest4j.AssertionFailedError: 
expected: [service0, service4, service3, service2, service1]
 but was: [service1, service2, service3, service4, service0]
	at example.OrderConsistencyTests.test(OrderConsistencyTests.java:28)
	at java.base/java.lang.reflect.Method.invoke(Method.java:580)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)

I'm not saying it's a bug because the Javadoc of @Order mentions collection but not map injection, since the serviceMap is a LinkedHashMap not a HashMap, I think it's better to keep the same order, but my test shows the order is declaration order.

Metadata

Metadata

Assignees

No one assigned

    Labels

    in: coreIssues in core modules (aop, beans, core, context, expression)status: supersededAn issue that has been superseded by another

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions