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 {

    }

}