Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve BeanFactory/ObjectProvider to select the only one default candidate among non-default candidates #34432

Closed
quaff opened this issue Feb 17, 2025 · 2 comments · May be fixed by pankratz76/spring-framework#1
Assignees
Labels
in: core Issues in core modules (aop, beans, core, context, expression) type: enhancement A general enhancement
Milestone

Comments

@quaff
Copy link
Contributor

quaff commented Feb 17, 2025

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 {

	}

}
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Feb 17, 2025
quaff added a commit to quaff/spring-framework that referenced this issue Feb 17, 2025
Close spring-projectsGH-34432

Signed-off-by: Yanming Zhou <zhouyanming@gmail.com>
@quaff
Copy link
Contributor Author

quaff commented Feb 17, 2025

My proposal: https://github.com/spring-projects/spring-framework/compare/main...quaff:patch-99?expand=1

@jhoeller jhoeller added the in: core Issues in core modules (aop, beans, core, context, expression) label Feb 17, 2025
@jhoeller jhoeller self-assigned this Feb 17, 2025
@jhoeller jhoeller added type: enhancement A general enhancement and removed status: waiting-for-triage An issue we've not yet triaged or decided on labels Feb 17, 2025
@jhoeller jhoeller added this to the 6.2.4 milestone Feb 17, 2025
@jhoeller
Copy link
Contributor

jhoeller commented Feb 18, 2025

@quaff good point, this is a general concern that can be taken into account in getBean(Class) just like the primary flag, even if no injection point with qualifier annotations is involved. However, this is semantically not quite "effectively primary", it is rather a last step of resolving a unique default among non-default candidates. I'll roll this into 6.2.4 (scheduled for release this Thursday).

@jhoeller jhoeller changed the title Improve BeanFactory/ObjectProvider to treat the only one default candidate as effectively @Primary Improve BeanFactory/ObjectProvider to select the only one default candidate among non-default candidates Feb 18, 2025
pankratz76 pushed a commit to pankratz76/spring-framework that referenced this issue Feb 24, 2025
Closes spring-projectsgh-34432

Signed-off-by: Vincent Potucek <vincent.potucek@sap.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: core Issues in core modules (aop, beans, core, context, expression) type: enhancement A general enhancement
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants