2011-11-09 18 views
9

Sto usando la seguente per la molla 3.1 configurazione:Spring configurazione 3.1: ambiente non iniettato

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

il problema è che la variabile env non viene iniettato ed è sempre nullo.

Non ho fatto nulla per la configurazione dell'ambiente poiché non so se è necessario o come. Ho guardato l'esempio della serra e non ho trovato nulla di specifico per l'ambiente. Cosa devo fare per assicurarmi che il env venga iniettato?

I file correlati:

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

} 

nel applicationContext.xml, è importate solo due XMLs da memorizzare nella cache config e Cassandra, quindi non possono essere importanti.

+0

Si sta utilizzando un server compatibile Java EE? – maks

risposta

1

Se non si utilizza un server Java EE completo compatibile, è necessario includere javax.inject.jar nel classpath del progetto per aggiungere il supporto di @Inject. Puoi anche provare a utilizzare l'annotazione nativa @Autowired di Spring.

+0

Grazie, Maks, l'inject.jar è lì. Questo progetto utilizzava la configurazione xml e funzionava correttamente con annotazioni. Sto cercando di vedere come va con 3.1 e non riesco a superare questo ostacolo. Deve mancare qualcosa che non riesco a capire. – jfd

+0

Hmm, ho provato a usare @inject con Environment nella primavera 3.1 e funziona perfettamente. Per favore, mostra la tua configurazione xml se è possibile – maks

+0

Ciao, Maks, aggiorno l'originale con più file lì. non so come aggiungere cose quaggiù. grazie – jfd

1

@jfd,

Non vedo subito qualcosa di sbagliato con la configurazione che potrebbe causare un errore di iniettare l'Ambiente.

Se si inizia da zero con una classe @Configuration vuota, quindi @Inject the Environment, funziona correttamente?

Se sì, allora a che punto inizia a fallire?

Sarebbe disposto a ridurre l'esempio fino alla configurazione più piccola possibile che non riesce e inviarlo come un progetto di riproduzione? Le istruzioni qui rendono questo più semplice possibile: https://github.com/SpringSource/spring-framework-issues#readme

Grazie!

+0

grazie Chris. quando spoglio tutto e gradualmente li aggiungo. Ho scoperto che secrityConfig.java è il problema che causa. Cerco ancora di capire perché. ma poi mi sono imbattuto in un altro problema che l'ibernato lamentava "Classe dialect non trovata: MYSQL" che era un non-problema in xml. quindi suppongo che la parte emf/transazione non sia ancora corretta – jfd

+0

Questo è troppo sottile. Ho trovato che ho bisogno di chiamare tutti i afterproperties se ce n'è uno, o tutto il postConstruct. è vero? un'altra cosa che ho ricevuto è che alcuni dei file di configurazione sono stati caricati e alcuni non hanno mai eseguito la scansione del pacchetto, quindi non di autowire non funziona poiché alcuni file di configurazione non sono mai stati richiamati. – jfd

+0

Ciao Chris, penso che il problema potrebbe essere con la sicurezza di primavera come ho scoperto. – jfd

2

Il problema è con la sicurezza di primavera per la funzione remember me. se prendo questa linea <code> <remember-me data-source-ref="dataSource" /> </code> out. tutto funziona bene se questa linea presenta, proverà a caricare il db prima di ogni altra cosa e non è mai stato iniettato env.

1

Ho rilevato un errore simile per il mio progetto come menzionato here. Ho anche capito che è necessario un richiamo di afterproperties per ottenere sessionFactory. ... e sì, sto usando anche Spring Security (che potrebbe essere la fonte del problema).

La mia classe annotata @Configuration utilizza @ComponentScan per i pacchetti contenenti DAO basati su Hibernate e un metodo annotato @Bean per la creazione di SessionFactory utilizzato dai DAO. In fase di runtime, viene generata un'eccezione, menzionato che "sessionFactory" o "hibernateTemplate" non sono stati trovati. Sembra che i DAO siano stati creati prima della creazione di SessionFactory. Una soluzione alternativa per me era di reinserire la direttiva di scansione dei componenti in un file XML() e sostituire @ComponentScan con @ImportResource di quel file.

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

anche fatto interessante: se @ComponentScan è incluso, un punto di interruzione impostato nel metodo sessionFactory() non è mai stato raggiunto!

+0

Ho passato questo problema inserendo un file di configurazione solo per la scansione e caricando quest'ultimo (usando @Import (xxx.class)). c'è molto da prestare attenzione quando si passa a java config: 1) chiamate di funzione afterproperty o postconstruct; 2) risorsa enum e percorso classe diversa dalle stringhe; 3) l'ambiente el stringa diversa dal vecchio modo di proprietà ecc. Alcuni di essi dovrebbero essere maneggiati nei macchinari primaverili come la cosa dell'anteproperty. – jfd

1

Avevo anche il problema simile con l'app di spring-social-sample.

Dopo aver convertito il livello del campo @Inject nel livello del costruttore, l'inchiostro ha funzionato.

5

Non so perché, ma l'utilizzo dell'annotazione @Resource ha funzionato per me. @Autowired ha sempre restituito null.

Problemi correlati