Testing Spring Boot 3.2.0-M2 which uses Spring Framework 6.1.0-M4, I found out a breaking change on autowiring logic, which might be by design, but I could not find any reference in the changelogs
The following scenario used to work:
@Bean. // Or @Bean(name = "stringA"), both approaches fail
private String stringA() {
return "A";
}
@Bean
private String stringB() {
return "B";
}
@Bean
private String test(String stringA) {
// First Bean is injected as it uses original name for untie
}
Now, for some reason, it gives me a NoUniqueBeanDefinitionException: expected single matching bean but found 2: stringA, stringB. I double checked the code and DependencyDescriptor.getDependencyName() returns null so DefaultListableBeanFactory.determineAutowireCandidate() cannot pick the appropiate candidate on the fallback matching-by-name logic
I wrote here a simplification, but for what is worth, in my real code, which I cannot share, the class is an AutoConfiguration, not a conventional @Configuration, and the injecting method ("test()" in the example), has a @ConditionalOnProperty
Comment From: nightswimmings
I debugged a bit more and found that I can only make it work if I use a @Qualifier("stringA")
in test(). Is this a new requirement by design? This used to work on Boot 2.x
Comment From: jhoeller
Did you compile with -parameters
? -debug
is not sufficient anymore as of 6.1. This is mentioned around the removal of LocalVariableTableParameterNameDiscoverer
: https://github.com/spring-projects/spring-framework/wiki/Upgrading-to-Spring-Framework-6.x
Comment From: quaff
@nightswimmings I can not reproduce with this test case
package com.example.demo;
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
@SpringJUnitConfig
public class SimpleTests {
@Autowired
private ApplicationContext ctx;
@Test
void test() {
assertThat(ctx.getBeanNamesForType(String.class)).containsExactlyInAnyOrder("stringA", "stringB", "test");
}
@Configuration
static class Config {
@Bean
String stringA() {
return "A";
}
@Bean
String stringB() {
return "B";
}
@Bean
String test(String stringA) {
return stringA;
}
}
}
Comment From: nightswimmings
Did you compile with
-parameters
?-debug
is not sufficient anymore as of 6.1. This is mentioned around the removal ofLocalVariableTableParameterNameDiscoverer
: https://github.com/spring-projects/spring-framework/wiki/Upgrading-to-Spring-Framework-6.x
I am really sorry to have missed that, but my issue was exactly fixed with your suggestion, so I will close the ticket. My apologies @quaff as well, thanks for helping me out