Closed
Description
Hello Spring-Team,
thank you for your continued work in maintaining this excellent framework. I've come across what appears to be an inconsistency in how qualifiers work in hierarchical contexts and wanted to bring it to your attention.
When using @Qualifier
annotations in a parent-child context hierarchy, qualifier values don't properly override field names, contradicting Spring's documented behaviour. Here is a simplified code sample:
// Parent context beans
@Bean({ "open.right","right"})
public TestInterface right() {
return () -> false;
}
@Bean({"open.left","left"})
public TestInterface left() {
return () -> true;
}
// Child context bean
private static class TestClass {
@Autowired
@Qualifier("open.left") // Should inject "left" bean
TestInterface right; // But field name is "right"
public boolean doit() {
return right.doItRight(); // Returns false instead of true
}
}
@Test
public void testInterface() {
AnnotationConfigApplicationContext subCtx = new AnnotationConfigApplicationContext();
subCtx.setParent(context);
subCtx.register(SubConfiguration.class);
subCtx.refresh();
// This assertion fails:
Assertions.assertTrue(subCtx.getBean(TestClass.class).doit());
}
Key elements:
- Parent context defines two beans of same type with different qualifiers
- Child context contains a bean with field using
@Qualifier
but mismatched field name - Despite
@Qualifier("open.left")
, the bean with name matching the field ("right") is injected
A full reproduction case is here: https://github.com/bcubk/spring-qualifier
Is this behaviour as expected or a bug? The qualifier resolution works as expected in a standard context but behaves differently in a parent-child hierarchy.
Environment
Spring Boot: 3.x
Spring Framework: 6.x
Java: 17