Uploaded image for project: 'Spring Framework'
  1. Spring Framework
  2. SPR-15829

Autowire contract is not honored in cases where FactoryBean or @Bean return null

    Details

    • Type: Improvement
    • Status: Closed
    • Priority: Major
    • Resolution: Complete
    • Affects Version/s: 5.0 RC3
    • Fix Version/s: 5.0 RC4
    • Component/s: Core
    • Labels:
      None
    • Last commented by a User:
      false

      Description

      Configuration below reproduces the issue

      @Autowired
      private FooStrategy foo;
       
      @Bean
      public FooStrategy createFoo() {
      	return null;
      }
      	
      public String doSomethingWithFoo(){
      	return foo.doSomething();;
      }
      

      The bottom line is that the above does NOT result in “Field foo in MyApplication required a bean of type 'FooStrategy' that could not be found.” And instead it results in NPE. But the NPE is not happening during AC initialization, rather during the invocation of any callback to 'foo'.

      Regardless of the reason to return null from the factory method, the main issue IMHO is that @Autowire contract is not followed for this type of scenario.

        Issue Links

          Activity

          Hide
          juergen.hoeller Juergen Hoeller added a comment -

          As discussed, we are enforcing a non-null value from getBean and at injection points now.

          Bean-derived null values may still get passed into bean properties and injection points but only if those are declared as non-required. Note that getBean will never return null; a manual bean.equals(null) / "null".equals(bean.toString()) check identifies expected null values now. This will only ever happen with custom FactoryBeans or factory methods returning null - and since all common cases are handled by autowiring or bean property values in bean definitions, there should be no need to ever manually check for such a null value received from getBean.

          Show
          juergen.hoeller Juergen Hoeller added a comment - As discussed, we are enforcing a non-null value from getBean and at injection points now. Bean-derived null values may still get passed into bean properties and injection points but only if those are declared as non-required. Note that getBean will never return null ; a manual bean.equals(null) / "null".equals(bean.toString()) check identifies expected null values now. This will only ever happen with custom FactoryBeans or factory methods returning null - and since all common cases are handled by autowiring or bean property values in bean definitions, there should be no need to ever manually check for such a null value received from getBean .
          Hide
          awilkinson Andy Wilkinson added a comment - - edited

          This change breaks Spring Data REST which has the following @Bean method in RepositoryRestMvcConfiguration:

          @Bean
          public JpaHelper jpaHelper() {
          	if (IS_JPA_AVAILABLE) {
          		return new JpaHelper();
          	} else {
          		return null;
          	}
          }
          

          https://github.com/spring-projects/spring-data-rest/blob/530e7c773e759f70076fc8cdb5b3f50b7be406f3/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/config/RepositoryRestMvcConfiguration.java#L271-L278

          Show
          awilkinson Andy Wilkinson added a comment - - edited This change breaks Spring Data REST which has the following @Bean method in RepositoryRestMvcConfiguration : @Bean public JpaHelper jpaHelper() { if (IS_JPA_AVAILABLE) { return new JpaHelper(); } else { return null ; } } https://github.com/spring-projects/spring-data-rest/blob/530e7c773e759f70076fc8cdb5b3f50b7be406f3/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/config/RepositoryRestMvcConfiguration.java#L271-L278
          Hide
          juergen.hoeller Juergen Hoeller added a comment -

          Indeed, we generally still accept such cases. As discussed with Stéphane Nicoll, there's an over-eager assertion in ConfigurationClassEnhancer trying to find type mismatches for @Bean cross-references. I'll sort that out right away...

          Show
          juergen.hoeller Juergen Hoeller added a comment - Indeed, we generally still accept such cases. As discussed with Stéphane Nicoll , there's an over-eager assertion in ConfigurationClassEnhancer trying to find type mismatches for @Bean cross-references. I'll sort that out right away...

            People

            • Assignee:
              juergen.hoeller Juergen Hoeller
              Reporter:
              ozhurakousky Oleg Zhurakousky
              Last updater:
              Stéphane Nicoll
            • Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:
                Days since last comment:
                3 weeks, 1 day ago