Skip to content

Null bean behaviors are different between method getBean(String name) and getBean(Class<T> requiredType ) #33792

New issue

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

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

Already on GitHub? # to your account

Closed
felixzhang0818 opened this issue Oct 25, 2024 · 1 comment
Labels
status: invalid An issue that we don't feel is valid

Comments

@felixzhang0818
Copy link

felixzhang0818 commented Oct 25, 2024

Background :
We defined a bean by @bean annotation in method level. Sometimes this method could return null. In the null-returning scenario, when we fetch instance by different getBean method, we found that the behaviors are different.

1, getBean(String name)
It returns a real object instance of "org.springframework.beans.factory.support.NullBean". This is a spring framework inner object.

2, getBean(Class requiredType )
It throws org.springframework.beans.factory.NoSuchBeanDefinitionException

Unit test to reproduce :

public class NullBeanTest {
    @Test
    void test() {
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(TestService.class, BeanFactory.class);

        Object obj1 = ctx.getBean("nullableBean");
        assertThat(obj1.getClass().getName()).isEqualTo("org.springframework.beans.factory.support.NullBean");

        Object obj2 = ctx.getBean(NullableBean.class);
        assertThat(obj2.getClass().getName()).isEqualTo("org.springframework.beans.factory.support.NullBean");

        ctx.close();
    }

    @Component
    @Scope("prototype")
    static class TestService {

        @Autowired
        private NullableBean nullableBean;

        public NullableBean getNullableBean() {
            return nullableBean;
        }
    }

    static class NullableBean{

    }

    @Component
    static class BeanFactory {

        @Bean("nullableBean")
        @Scope("prototype")
        public NullableBean create(){
            return null;
        }
    }
}

Asks :
For the null bean, we might have 3 options for the returning of getBean method

  • Option1, directly return null
  • Option2, return the instance of inner null object - org.springframework.beans.factory.support.NullBean
  • Option3, throw exception
  1. From spring framework perspective, what is the official finalized behavior ?
  2. Can we make the behavior consistent in each getBean method and other methods also used for getBean purpose ?
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Oct 25, 2024
@jhoeller
Copy link
Contributor

jhoeller commented Oct 25, 2024

We used to return null from getBean(name) before Spring Framework 5.0 there but tightened this as part of our null-safety efforts. This behavior has been in place for several years already, so we do not intend to revisit it at this point.

The reason for the different behavior is that a null bean is not of the specified required type, so not encountered as a match by getBean(type). Note that getBean(type) is effectively a type-matching retrieval method, a sort of simple version of getBeansOfType, whereas getBean(name) is a straight lookup by id. In Spring, beans are always registered by name; the type is a secondary characteristic that can be used for retrieval but does not identify a specific bean.

In practice, avoid null beans wherever you can. You might be able to conditionally register a bean instead. Pretending a bean is defined but then returning null from its factory method was always a fragile arrangement, and as of Spring Framework 5.0 we do not consider this first class anymore. We rather just tolerate it for some degree of backwards compatibility with such factory methods in existing application code. Consistent behavior is not a goal there, just tolerance of certain arrangements.

@jhoeller jhoeller closed this as not planned Won't fix, can't repro, duplicate, stale Oct 25, 2024
@jhoeller jhoeller added status: invalid An issue that we don't feel is valid and removed status: waiting-for-triage An issue we've not yet triaged or decided on labels Oct 25, 2024
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
status: invalid An issue that we don't feel is valid
Projects
None yet
Development

No branches or pull requests

3 participants