title: How do I ensure dependent configurations are initialized with Spring @Configuration annotation?
body: <p>I am trying to use @Configuration annotations to wire up my application but I keep getting a NullPointerException in one of the initializers because the bean it refers to is not yet initialized (I think).  I have tried specifying in the web.xml just the 'root' config class and also tried doing a package scan and neither seem to work.</p>
  
  <p>Sorry about the big code dump.  <em>I tried to produce a much simpler set of classes to reproduce the issue, but of course, when I did that, everything worked fine.</em>  Here are my classes (imports elided):</p>
  
  <p>DataSourceConfig.java:</p>
  
  <pre><code>@Configuration
  public class DataSourceConfig {
  
      public DataSourceConfig() {
          System.err.println("DataSourceConfig constructed...");
      }
  
      @Bean
      public DataSource dataSource() {
          BasicDataSource bean = new BasicDataSource();
          bean.setDriverClassName("com.mysql.jdbc.Driver");
          bean.setUrl("jdbc:mysql://localhost:3306/observation");
          bean.setUsername("observation");
          bean.setPassword("*******");
          bean.setInitialSize(1);
          bean.setMaxActive(5);
          bean.setTestOnBorrow(true);
          System.err.println("dataSource bean initialized: " + bean.toString());
          return bean;
      }
  }
  </code></pre>
  
  <p>HibernateConfig.java</p>
  
  <pre><code>@Configuration
  @Import(DataSourceConfig.class)
  public class HibernateConfig {
  
      public HibernateConfig() {
          System.err.println("HibernateConfig constructing...");
      }
  
      @Autowired
      private DataSourceConfig dataSourceConfig;
  
      @Bean
      protected NamingStrategy namingStrategy() {
          return new ImprovedNamingStrategy();
      }
  
      private AnnotationSessionFactoryBean sessionFactoryBean = null;
  
      @Bean
      @DependsOn("dataSourceConfig")
      public AnnotationSessionFactoryBean sessionFactory() {
          if (sessionFactoryBean == null) {
              sessionFactoryBean = new AnnotationSessionFactoryBean();
  NPE Here--&gt; sessionFactoryBean.setDataSource(dataSourceConfig.dataSource()); 
              sessionFactoryBean.setSchemaUpdate(true);
              sessionFactoryBean.setNamingStrategy(namingStrategy());
              sessionFactoryBean.setPackagesToScan(new String[] {
                      "com.newco.observations.domain",
                      "com.newco.observations.domain.*" });
              Properties props = new Properties();
              props.setProperty("hibernate.default_schema", "observation");
              props.setProperty("hibernate.dialect",
                      "org.hibernate.dialect.MySQLDialect");
              props.setProperty("hibernate.show_sql", "true");
              sessionFactoryBean.setHibernateProperties(props);
              System.err.println("sessionFactory initialized");
          }
          return sessionFactoryBean;
      }
  
      @Bean
      @DependsOn("dataSourceConfig")
      public JdbcTemplate jdbcTemplate() {
          return new JdbcTemplate(dataSourceConfig.dataSource());
      }
  
      @Bean
      @DependsOn("sessionFactory")
      public ResourceTransactionManager txManager() {
          HibernateTransactionManager bean = new HibernateTransactionManager();
          bean.setSessionFactory((SessionFactory) sessionFactory().getObject());
          return bean;
      }
  
      @Bean
      @DependsOn("sessionFactory")
      public HibernateTemplate hibernateTemplate() {
          return new HibernateTemplate((SessionFactory) sessionFactory()
                  .getObject());
      }
  }
  </code></pre>
  
  <p>DaoConfig.java:</p>
  
  <pre><code>@Configuration
  @Import(HibernateConfig.class)
  public class DaoConfig {
  
      public DaoConfig()
      {
          System.err.println("DaoConfig constructing...");
      }
  
      private @Autowired HibernateConfig hibernateConfig;
  
      @Bean
      @DependsOn("hibernateTemplate")
      public PhenomenonGroupDao phenomenonGroupDao()
      {
          PhenomenonGroupDaoImpl bean = new PhenomenonGroupDaoImpl();
          bean.setHibernateTemplate(hibernateConfig.hibernateTemplate());
          return bean;
      }
  
      @Bean
      @DependsOn("hibernateTemplate")
      public PhenomenonDao phenomenonDao()
      {
          PhenomenonDaoImpl bean = new PhenomenonDaoImpl();
          bean.setHibernateTemplate(hibernateConfig.hibernateTemplate());
          return bean;
      }
  
      @Bean
      @DependsOn("hibernateTemplate")
      public DiscretePhenomenonDao discretePhenomenonDao()
      {
          DiscretePhenomenonDaoImpl bean = new DiscretePhenomenonDaoImpl();
          bean.setHibernateTemplate(hibernateConfig.hibernateTemplate());
          return bean;
      }
  
  
  }
  </code></pre>
  
  <p>You can see from the System.err.println's and the @DependsOn annotations a kind of flailing about that I'm doing.</p>
  
  <p>I can provide the full log if it's useful, but here is what I think are the relevant lines (with a little formatting to make it more readable (maybe)):</p>
  
  <ul>
  <li>208  [Thread-0] INFO  org.springframework.context.annotation.ConfigurationClassEnhancer</li>
  <li>Successfully enhanced com.bjk.observation.server.config.DaoConfig; enhanced class name is: com.bjk.observation.server.config.DaoConfig$$EnhancerByCGLIB$$96e1956 </li>
  <li>229  [Thread-0] INFO  org.springframework.beans.factory.support.DefaultListableBeanFactory</li>
  <li>Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@185572a: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor, org.springframework.context.annotation.internalAutowiredAnnotationProcessor, org.springframework.context.annotation.internalRequiredAnnotationProcessor, org.springframework.context.annotation.internalCommonAnnotationProcessor, org.springframework.context.annotation.internalPersistenceAnnotationProcessor, daoConfig,com.bjk.observation.server.config.DataSourceConfig#0, dataSource, com.bjk.observation.server.config.HibernateConfig#0, namingStrategy, sessionFactory, jdbcTemplate, txManager, hibernateTemplate, phenomenonGroupDao, phenomenonDao, discretePhenomenonDao]; root of factory hierarchy DaoConfig constructing... </li>
  <li>252  [Thread-0] INFO  org.springframework.beans.factory.support.DefaultListableBeanFactory</li>
  <li>Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@185572a: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor, org.springframework.context.annotation.internalAutowiredAnnotationProcessor, org.springframework.context.annotation.internalRequiredAnnotationProcessor, org.springframework.context.annotation.internalCommonAnnotationProcessor, org.springframework.context.annotation.internalPersistenceAnnotationProcessor, daoConfig, com.bjk.observation.server.config.DataSourceConfig#0, dataSource, com.bjk.observation.server.config.HibernateConfig#0, namingStrategy, sessionFactory, jdbcTemplate, txManager, hibernateTemplate, phenomenonGroupDao, phenomenonDao, discretePhenomenonDao]; root of factory hierarchy </li>
  <li>253  [Thread-0] ERROR org.springframework.web.context.ContextLoader</li>
  <li>Context initialization failed org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'daoConfig': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.bjk.observation.server.config.HibernateConfig com.bjk.observation.server.config.DaoConfig.hibernateConfig; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.bjk.observation.server.config.HibernateConfig#0': Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.bjk.observation.server.config.HibernateConfig]: Constructor threw exception; nested exception is java.lang.NullPointerException</li>
  </ul>