Spring Framework
  1. Spring Framework
  2. SPR-10546

Loading @Import(ChildConfig) or EnclosingConfig.ChildConfig and then ChildConfig does not load beans on ParentConfig

    Details

    • Type: Bug Bug
    • Status: Resolved
    • Priority: Minor Minor
    • Resolution: Complete
    • Affects Version/s: 3.2.2
    • Fix Version/s: 3.2.3, 4.0 M1
    • Component/s: Core:DI
    • Labels:
      None
    • Last commented by a User:
      false

      Description

      Given the following configuration:

      @Configuration
      static class ParentConfig {
        @Bean
        public String myBean() {
          return "myBean";
        }
      }
      
      @Configuration
      static class EnclosingConfig {
        @Configuration
        public static class ChildConfig extends ParentConfig {}
      }
      

      The following will succeed:

      AnnotationConfigApplicationContext context = 
        new AnnotationConfigApplicationContext(EnclosingConfig.ChildConfig.class,EnclosingConfig.class);
      context.getBean(String.class)
      

      The following will fail:

      AnnotationConfigApplicationContext context = 
        new AnnotationConfigApplicationContext(EnclosingConfig.class, EnclosingConfig.ChildConfig.class);
      context.getBean(String.class)
      

      The reason this fails is the following happens:

      • ConfigurationClassParser#doProcessConfigurationClass parses EnclosingConfig
      • It then processes the member classes which includes EnclosingConfig.ChildConfig
      • ConfigurationClassParser#doProcessConfigurationClass parses EnclosingConfig.ChildConfig
      • ConfigurationClassParser#doProcessConfigurationClas parses EnclosingConfig.ChildConfig's parent class ParentConfig
      • myBean is added as a method to EnclosingConfig.ChildConfig's configClass
      • ParentConfig is marked to not be processed again by adding it to knownSuperclasses
      • ConfigurationClassParser#doProcessConfigurationClass parses EnclosingConfig.ChildConfig and does not attempt to process the super class because it is already in knownSuperclasses. Because of this, the configClass with this ConfigurationClass does not have any beanMethods from the super class
      • ConfigurationClassParser.processConfigurationClass removes the existing instance of ConfigurationClass which has the beanMethods form ParentConfig on it
      • The EnclosingConfig.ChildConfig that does not have the beanMethods from the ParentConfig on it is then added to the configurationClasses

      It might be relevant to note that the failure and success depends on if the first @Configuration has name or not. If second Configuration does not have a bean name, then it is not overridden.

      Another example would be given:

      @Configuration
      static class ParentConfig {
        @Bean
        public String myBean() {
          return "myBean";
        }
      }
      @Configuration
      static class ChildConfig extends ParentConfig {}
      
      @Configuration
      @Import(ChildConfig.class)
      static class ImportChildConfig {}
      

      The following will succeed:

      AnnotationConfigApplicationContext context = 
        new AnnotationConfigApplicationContext(ChildConfig.class,ImportChildConfig.class);
      context.getBean(String.class)
      

      The following will fail:

      AnnotationConfigApplicationContext context = 
        new AnnotationConfigApplicationContext(ImportChildConfig.class, ChildConfig.class);
      context.getBean(String.class)
      

      Please note that this issue can happen when using classpath scanning, so this can be quite difficult to track down if the classes are discovered in a different order. The classpath scanning (at least for my system) seems to be implemented to order the classes alphabetically. I have not dug into the internals of the classpath scanning implementation to determine if this is environment specific or not.

        Activity

        Hide
        Rob Winch added a comment -
        Show
        Rob Winch added a comment - Pull request submitted https://github.com/SpringSource/spring-framework/pull/282

          People

          • Assignee:
            Juergen Hoeller
            Reporter:
            Rob Winch
            Last updater:
            Juergen Hoeller
          • Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:
              Days since last comment:
              48 weeks, 5 days ago