We can inject the default candidate when other candidates are non-default, but there is no way to get the default candidate from BeanFactory
unless we know the bean name, sometimes the bean name is volatile or not visible to application, for example registered by Spring Boot's AutoConfiguration.
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
@SpringJUnitConfig
class SimpleTests {
@Autowired
private BeanFactory beanFactory;
@Autowired
private Service defaultService;
@Autowired
@Qualifier("additionalService")
private Service additionalService;
@Test
void testGetBean() {
assertThat(beanFactory.getBean(Service.class)).isSameAs(defaultService);
// failed due to NoUniqueBeanDefinitionException
}
@Test
void testGetBeanProvider() {
assertThat(beanFactory.getBeanProvider(Service.class).getObject()).isSameAs(defaultService);
// failed due to NoUniqueBeanDefinitionException
}
@Test
void testGetBeanWithName() {
assertThat(beanFactory.getBean("additionalService", Service.class)).isSameAs(additionalService);
}
@Configuration
static class Config {
@Bean(name = "auto-generated-name-unknown-to-application")
Service defaultService() {
return new Service();
}
@Bean(defaultCandidate = false)
Service additionalService() {
return new Service();
}
}
static class Service {
}
}