2011-11-09 10 views
9

estoy usando lo siguiente para la primavera 3,1 configuración:primavera configuración 3.1: medio ambiente no inyecta

@Configuration 
@EnableTransactionManagement 
public class DataConfig { 
    @Inject 
    private Environment env; 
    @Inject 
    private DataSource dataSource; 

    // @Bean 
    public SpringLiquibase liquibase() { 
     SpringLiquibase b = new SpringLiquibase(); 
     b.setDataSource(dataSource); 
     b.setChangeLog("classpath:META-INF/db-changelog-master.xml"); 
     b.setContexts("test, production"); 
     return b; 
    } 

    @Bean 
    public EntityManagerFactory entityManagerFactory() { 
     LocalContainerEntityManagerFactoryBean b = new LocalContainerEntityManagerFactoryBean(); 
     b.setDataSource(dataSource); 
     HibernateJpaVendorAdapter h = new HibernateJpaVendorAdapter(); 
     h.setShowSql(env.getProperty("jpa.showSql", Boolean.class)); 
     h.setDatabasePlatform(env.getProperty("jpa.database")); 

     b.setJpaVendorAdapter(h); 
     return (EntityManagerFactory) b; 
    } 

    @Bean 
    public PersistenceExceptionTranslationPostProcessor persistenceExceptionTranslationPostProcessor() { 
     PersistenceExceptionTranslationPostProcessor b = new PersistenceExceptionTranslationPostProcessor(); 
     // b.setRepositoryAnnotationType(Service.class); 
     // do this to make the persistence bean post processor pick up our @Service class. Normally 
     // it only picks up @Repository 
     return b; 

    } 

    @Bean 
    public PlatformTransactionManager transactionManager() { 
     JpaTransactionManager b = new JpaTransactionManager(); 
     b.setEntityManagerFactory(entityManagerFactory()); 
     return b; 
    } 

    /** 
    * Allows repositories to access RDBMS data using the JDBC API. 
    */ 
    @Bean 
    public JdbcTemplate jdbcTemplate() { 
     return new JdbcTemplate(dataSource); 
    } 


    @Bean(destroyMethod = "close") 
    public DataSource dataSource() { 

     BasicDataSource db = new BasicDataSource(); 
     if (env != null) { 
      db.setDriverClassName(env.getProperty("jdbc.driverClassName")); 
      db.setUsername(env.getProperty("jdbc.username")); 
      db.setPassword(env.getProperty("jdbc.password")); 
     } else { 
      throw new RuntimeException("environment not injected"); 
     } 
     return db; 
    } 
} 

el problema es que la variable env no se inyecta y siempre es nula.

No he hecho nada acerca de la configuración del entorno ya que no sé si es necesario o cómo hacerlo. Miré el ejemplo del invernadero y no encontré nada específicamente para el medio ambiente. ¿Qué debo hacer para asegurarme de que se inyecte el env?

Los archivos relacionados:

// CoreConfig.java 
@Configuration 
public class CoreConfig { 

    @Bean 
    LocalValidatorFactoryBean validator() { 
     return new LocalValidatorFactoryBean(); 
    } 

    /** 
    * Properties to support the 'standard' mode of operation. 
    */ 
    @Configuration 
    @Profile("standard") 
    @PropertySource("classpath:META-INF/runtime.properties") 
    static class Standard { 
    } 

} 


// the Webconfig.java 
@Configuration 
@EnableWebMvc 
@EnableAsync 
// @EnableScheduling 
@EnableLoadTimeWeaving 
@ComponentScan(basePackages = "com.jfd", excludeFilters = { @Filter(Configuration.class) }) 
@Import({ CoreConfig.class, DataConfig.class, SecurityConfig.class }) 
@ImportResource({ "/WEB-INF/spring/applicationContext.xml" }) 
public class WebConfig extends WebMvcConfigurerAdapter { 


    @Override 
    public void addResourceHandlers(ResourceHandlerRegistry registry) { 
     registry.addResourceHandler("/images/**").addResourceLocations(
       "/images/"); 
    } 

    @Bean 
    public BeanNameViewResolver beanNameViewResolver() { 
     BeanNameViewResolver b = new BeanNameViewResolver(); 
     b.setOrder(1); 
     return b; 
    } 

    @Bean 
    public InternalResourceViewResolver internalResourceViewResolver() { 
     InternalResourceViewResolver b = new InternalResourceViewResolver(); 
     b.setSuffix(".jsp"); 
     b.setPrefix("/WEB-INF/jsp/"); 
     b.setOrder(2); 
     return b; 
    } 

    @Bean 
    public CookieLocaleResolver localeResolver() { 
     CookieLocaleResolver b = new CookieLocaleResolver(); 
     b.setCookieMaxAge(100000); 
     b.setCookieName("cl"); 
     return b; 
    } 

    // for messages 
    @Bean 
    public ResourceBundleMessageSource messageSource() { 
     ResourceBundleMessageSource b = new ResourceBundleMessageSource(); 
     b.setBasenames(new String[] { "com/jfd/core/CoreMessageResources", 
       "com/jfd/common/CommonMessageResources", 
       "com/jfd/app/AppMessageResources", 
       "com/jfd/app/HelpMessageResources" }); 
     b.setUseCodeAsDefaultMessage(false); 
     return b; 
    } 

    @Bean 
    public SimpleMappingExceptionResolver simpleMappingExceptionResolver() { 
     SimpleMappingExceptionResolver b = new SimpleMappingExceptionResolver(); 

     Properties mappings = new Properties(); 
     mappings.put("org.springframework.web.servlet.PageNotFound", "p404"); 
     mappings.put("org.springframework.dao.DataAccessException", 
       "dataAccessFailure"); 
     mappings.put("org.springframework.transaction.TransactionException", 
       "dataAccessFailure"); 
     b.setExceptionMappings(mappings); 
     return b; 
    } 

    /** 
    * ViewResolver configuration required to work with Tiles2-based views. 
    */ 
    @Bean 
    public ViewResolver viewResolver() { 
     UrlBasedViewResolver viewResolver = new UrlBasedViewResolver(); 
     viewResolver.setViewClass(TilesView.class); 
     return viewResolver; 
    } 

    /** 
    * Supports FileUploads. 
    */ 
    @Bean 
    public MultipartResolver multipartResolver() { 
     CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(); 
     multipartResolver.setMaxUploadSize(500000); 
     return multipartResolver; 
    } 

    // for configuration 
    @Bean 
    public CompositeConfigurationFactoryBean myconfigurations() 
      throws ConfigurationException { 
     CompositeConfigurationFactoryBean b = new CompositeConfigurationFactoryBean(); 
     PropertiesConfiguration p = new PropertiesConfiguration(
       "classpath:META-INF/app-config.properties"); 
     p.setReloadingStrategy(new FileChangedReloadingStrategy()); 

     b.setConfigurations(new org.apache.commons.configuration.Configuration[] { p }); 
     b.setLocations(new ClassPathResource[] { new ClassPathResource(
       "META-INF/default-config.properties") }); 
     return b; 
    } 

    @Bean 
    org.apache.commons.configuration.Configuration configuration() 
      throws ConfigurationException { 
     return myconfigurations().getConfiguration(); 
    } 


// and the SecurityConfig.java 
@Configuration 
@ImportResource({ "/WEB-INF/spring/applicationContext-security.xml" }) 
public class SecurityConfig { 

    @Bean 
    public BouncyCastleProvider bcProvider() { 
     return new BouncyCastleProvider(); 
    } 

    @Bean 
    public PasswordEncryptor jasyptPasswordEncryptor() { 

     ConfigurablePasswordEncryptor b = new ConfigurablePasswordEncryptor(); 
     b.setAlgorithm("xxxxxx"); 
     return b; 
    } 

    @Bean 
    public PasswordEncoder passwordEncoder() { 
     PasswordEncoder b = new org.jasypt.spring.security3.PasswordEncoder(); 
     b.setPasswordEncryptor(jasyptPasswordEncryptor()); 
     return b; 
    } 

} 

en el applicationContext.xml, sólo importan dos XMLs a cache de configuración y Cassandra, por lo que puede no ser importante.

+0

¿Está utilizando un servidor compatible con Java EE? – maks

Respuesta

1

Si no utiliza el servidor completo compatible con Java EE, debe incluir javax.inject.jar en la classpath del proyecto para agregar el soporte de @Inject. También puede intentar utilizar la anotación nativa de spring @Autowired.

+0

Gracias, Maks, el inject.jar está ahí. Este proyecto usaba configuración xml y funcionaba bien con anotaciones. Estoy tratando de ver cómo va con 3.1 y no puedo pasar este obstáculo. Debe pasar por alto algo que no puedo descifrar. – jfd

+0

Hmm, he intentado usar @inject con Environment en la primavera 3.1 y funciona bien. Por favor, muestre su configuración xml si es posible – maks

+0

Hola, Maks, actualizo el original con más archivos allí. No sé cómo agregar cosas aquí. gracias – jfd

1

@jfd,

No veo nada malo de inmediato con la configuración que podría causar un fallo de inyectar el medio ambiente.

Si comienza desde cero con una clase @Configuration vacía, y luego @Inject the Environment, ¿le funciona?

En caso afirmativo, ¿en qué punto comienza a fallar?

¿Estaría dispuesto a reducir el ejemplo a la configuración más pequeña posible que falle y enviarla como un proyecto de reproducción? Las instrucciones aquí lo hacen lo más simple posible: https://github.com/SpringSource/spring-framework-issues#readme

¡Gracias!

+0

gracias Chris. cuando lo despojo todo y gradualmente lo vuelvo a agregar. Descubrí que secrityConfig.java es el problema que causa. Aún intenta averiguar por qué. pero luego me quedé con otro problema que hibernate quejándose "Dialect class not found: MYSQL" que no era un problema en xml. así que supongo que la parte emf/transacción aún no es correcta – jfd

+0

Esto es demasiado sutil. Descubrí que necesito llamar a todas las propiedades posteriores si hay una, o todas las postConstrucciones. ¿es eso cierto? Otra cosa que obtuve es que algunos de los archivos de configuración están cargados y algunos nunca escanean el paquete, por lo que Autowire no funciona, ya que algunos de los archivos de configuración nunca se llamaron. – jfd

+0

Hola Chris, creo que el problema podría ser con la seguridad de primavera como descubrí. – jfd

2

El problema es con la seguridad de primavera para la función de recordarme. si tomo esta línea <code> <remember-me data-source-ref="dataSource" /> </code>. todo funciona bien si esta línea se presenta, intentará cargar el db antes que cualquier otra cosa y env nunca se inyectará.

1

He detectado un error similar para mi proyecto como se menciona here. También me di cuenta de que una llamada de afterproperties es necesaria para obtener sessionFactory. ... y sí, estoy usando Spring Security también (que puede ser el origen del problema).

Mi clase anotada @Configuration usa @ComponentScan para paquetes que contienen HBO en DAO basados ​​y un método @Bean anotado para crear el SessionFactory utilizado por los DAO. En el tiempo de ejecución, se lanza una excepción, se menciona que 'sessionFactory' o 'hibernateTemplate' no se encontraron. Parece que los DAO se construyen antes de que se creara SessionFactory. Una solución para mí fue volver a colocar la directiva de escaneo de componentes en un archivo XML() y reemplazar @ComponentScan con @ImportResource de ese archivo.

@Configuration 
//@ComponentScan(basePackages = "de.webapp.daocustomer", excludeFilters = {@ComponentScan.Filter(Configuration.class), @ComponentScan.Filter(Controller.class)}) 
@ImportResource({"classpath*:componentScan.xml","classpath*:properties-config.xml","classpath*:security-context.xml"}) 
public class AppConfig 
{ 
... 
@Bean 
public SessionFactory sessionFactory() throws Exception 
{ 
    AnnotationSessionFactoryBean bean = new AnnotationSessionFactoryBean(); 
    bean.setDataSource(dataSource()); 
    bean.setPackagesToScan(new String[] {"de.webapp"}); 
    bean.setHibernateProperties(hibernateProps()); 
    bean.afterPropertiesSet(); 
    return bean.getObject(); 
} 

también hecho interesante: si @ComponentScan se incluye, no se llegó a establecer un punto de interrupción en el método sessionFactory()!

+0

Pasé ese problema al poner un archivo de configuración para escanear únicamente y cargarlo último (usando @Import (xxx.class)). hay mucho que prestar atención mientras se mueve a la configuración de java: 1) después de llamadas de función de propiedad o postconstrucción; 2) enum y recurso de ruta de clase que no sean cadenas; 3) Entorno el hilo que no sea el viejo modo de propiedad, etc. algunos de ellos deben manejarse en la maquinaria de primavera como la cosa posterior a la propiedad. – jfd

1

También tuve el problema similar con la aplicación spring-social-sample.

Después de convertir el nivel de campo @Inject al nivel de constructor inyectar, funcionó.

5

No estoy seguro de por qué, pero utilizando la anotación @Resource funcionó para mí. @Autowired siempre devolvió null.

Cuestiones relacionadas