2010-07-16 13 views
5

Sto tentando di utilizzare le annotazioni @Configuration per collegare la mia applicazione, ma continuo a ricevere NullPointerException in uno degli inizializzatori perché il bean a cui fa riferimento non è ancora inizializzato (credo). Ho provato a specificare nel web.xml solo la classe di configurazione 'root' e ho anche provato a fare una scansione del pacchetto e nessuno dei due sembra funzionare.Come posso garantire che le configurazioni dipendenti siano inizializzate con l'annotazione Spring @Configuration?

Ci scusiamo per il grande dump del codice. Ho provato a produrre un insieme di classi molto più semplice per riprodurre il problema, ma ovviamente, quando l'ho fatto, tutto ha funzionato bene. Qui ci sono le mie classi (importazioni): elise

DataSourceConfig.java:

@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; 
    } 
} 

HibernateConfig.java

@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--> 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()); 
    } 
} 

DaoConfig.java:

@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; 
    } 


} 

Si può vedere dalla le annotazioni System.err.println e @DependsOn un tipo di agitazione su t cappello che sto facendo

posso fornire il registro completo se è utile, ma qui è quello che penso sono le linee interessate (con un po 'di formattazione per renderlo più leggibile (forse)):

  • 208 [Thread-0 ] INFO org.springframework.context.annotation.ConfigurationClassEnhancer
  • Migliorato con successo com.bjk.observation.server.config.DaoConfig; migliorato nome della classe è: com.bjk.observation.server.config.DaoConfig $$ EnhancerByCGLIB $$ 96e1956
  • 229 [Thread-0] INFO org.springframework.beans.factory.support.DefaultListableBeanFactory
  • single Pre-istanziare in org.s[email protected]185572a: definizione dei bean [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, namings trategy, sessionFactory, jdbcTemplate, txManager, hibernateTemplate, phenomenonGroupDao, fenomeniDao, discretePenomenonDao; radice della gerarchia di fabbrica DaoConfig costruire ...
  • 252 [Thread-0] INFO org.springframework.beans.factory.support.DefaultListableBeanFactory
  • singletons Distruggere in org.s[email protected]185572a: definizione dei bean [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 ,DaoDao, discretePenomenonDao; root of factory hierarchy
  • 253 [Thread-0] ERROR org.springframework.web.context.ContextLoader
  • Inizializzazione del contesto non riuscita org.springframework.beans.factory.BeanCreationException: errore durante la creazione di bean con nome 'daoConfig': Iniezione delle dipendenze autowired non riuscita; l'eccezione annidata è org.springframework.beans.factory.BeanCreationException: Impossibile eseguire il campo autowire: private com.bjk.observation.server.config.HibernateConfig com.bjk.observation.server.config.DaoConfig.hibernateConfig; l'eccezione annidata è org.springframework.beans.factory.BeanCreationException: errore nella creazione di bean con nome 'com.bjk.observation.server.config.HibernateConfig # 0': Instantiation of bean failed; l'eccezione annidata è org.springframework.beans.BeanInstantiationException: impossibile istanziare la classe bean [com.bjk.observation.server.config.HibernateConfig]: il costruttore ha lanciato un'eccezione; l'eccezione annidata è java.lang.NullPointerException

risposta

2

Il problema, a mio avviso è qui:

@Autowired 
private DataSourceConfig dataSourceConfig; 

Non dovresti cablare esplicitamente te stesso con le altre classi @Configuration -annotated, ma piuttosto i fagioli che loro producono. La primavera sistemerà l'impianto idraulico per te.

Quindi sostituire il campo sopra con il più semplice:

@Autowired 
private DataSource dataSource; 

primavera verrà recuperato il DataSource da DataSourceConfig e trasparente iniettarlo nel campo.

Allo stesso modo, sostituire

@Autowired 
private HibernateConfig hibernateConfig; 

con

@Autowired 
private HibernateTemplate hibernateTemplate; 

Si noterà che lo stile @Configuration non si sente così bello quando si lavora con i fagioli di fabbrica come AnnotationSessionFactoryBean, dal momento che spesso si devono chiamare getObject() da solo. A volte, è più naturale usare la configurazione XML e mescolarla con lo stile di configurazione java.

+3

Non so perché questo sarebbe d'aiuto esattamente perché le classi contrassegnate con @Configuration dovrebbero essere bean a se stanti. Tuttavia, ho provato come suggerito e sebbene il mio registro degli errori sia diverso, ha ancora a che fare con i bean che non vengono inizializzati nell'ordine corretto. (Il debugger lo conferma) Prendo il vostro punto sul fatto che @Configuration non è bello per i bean factory e infatti, sono tornato alla vecchia affidabile configurazione xml, ma mi piacerebbe comunque capire come funziona _supposed_. – jhericks

Problemi correlati