Estoy tratando de utilizar las anotaciones @Configuration para conectar mi aplicación pero sigo obteniendo una NullPointerException en uno de los inicializadores porque el bean al que se refiere todavía no se ha inicializado (creo). Intenté especificar en el web.xml solo la clase de configuración 'raíz' y también intenté hacer un escaneo de paquetes y ninguno de los dos parece funcionar.¿Cómo me aseguro de que las configuraciones dependientes se inicialicen con la anotación Spring @Configuration?
Disculpa por el gran volcado de código. Traté de producir un conjunto de clases mucho más simple para reproducir el problema, pero por supuesto, cuando lo hice, todo funcionó bien. Aquí están mis clases (importaciones): elididas
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;
}
}
Se puede ver desde las anotaciones System.err.println y @DependsOn una especie de sacudida sobre t que estoy haciendo
puedo proporcionar el registro completo si es útil, pero aquí es lo que creo que son las líneas relevantes (con un poco de formato para que sea más fácil de leer (tal vez)):
- 208 [Thread-0 ] INFO org.springframework.context.annotation.ConfigurationClassEnhancer
- Mejorado con éxito com.bjk.observation.server.config.DaoConfig; nombre de la clase mejorada es: com.bjk.observation.server.config.DaoConfig $$ $$ EnhancerByCGLIB 96e1956
- 229 [thread-0] Información org.springframework.beans.factory.support.DefaultListableBeanFactory
- únicos-crear instancias de Pre en org.springframework.beans.factory.support.DefaultLista[email protected]: definición de 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, nombres trategy, sessionFactory, jdbcTemplate, txManager, hibernateTemplate, phenomenonGroupDao, phenomenonDao, discretePhenomenonDao]; raíz de la jerarquía de la fábrica DaoConfig la construcción ...
- 252 [thread-0] Información org.springframework.beans.factory.support.DefaultListableBeanFactory
- únicos destruyendo en org.s[email protected]185572a: granos que definen [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]; raíz de la jerarquía de fábrica
- 253 [Thread-0] ERROR org.springframework.web.context.ContextLoader
- Error al inicializar el contexto org.springframework.beans.factory.BeanCreationException: error al crear bean con el nombre 'daoConfig': error en la inyección de dependencias con autoenlace; la excepción anidada es org.springframework.beans.factory.BeanCreationException: no se pudo autocablear el campo: privado com.bjk.observation.server.config.HibernateConfig com.bjk.observation.server.config.DaoConfig.hibernateConfig; La excepción anidada es org.springframework.beans.factory.BeanCreationException: Error al crear bean con el nombre 'com.bjk.observation.server.config.HibernateConfig # 0': Error de instanciación del bean; La excepción anidada es org.springframework.beans.BeanInstantiationException: No se pudo crear una instancia de la clase bean [com.bjk.observation.server.config.HibernateConfig]: Constructor lanzó una excepción; la excepción jerarquizada es java.lang.NullPointerException
No sé por qué eso ayudaría exactamente porque se supone que las clases marcadas con @Configuration son beans en sí mismas. No obstante, probé como sugirió y, aunque mi registro de errores es diferente, todavía tiene que ver con que los beans no se inicialicen en el orden correcto. (El depurador lo confirma). Considero que @Configuration no es tan agradable para los beans de fábrica y, de hecho, me he encontrado con una configuración xml fiable, pero aún me gustaría entender cómo se supone que funciona. – jhericks