2011-11-09 70 views
9

我使用下面的春季3.1配置:春3.1配置:環境不注射

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

的問題是,可變env沒有注入和始終爲空。

我還沒有做過關於環境設置的任何內容,因爲我不知道它是否需要或如何使用。我看着溫室的例子,我沒有找到任何專門針對環境的東西。我應該怎麼做才能確保env被注入?

的相關文件:

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

} 
在applicationContext.xml

,它僅進口2個XML來配置緩存和卡桑德拉,所以它可能不會是非常重要的。

+0

您使用的是Java EE兼容服務器嗎? – maks

回答

1

如果您不使用完整的Java EE兼容服務器,則必須將javax.inject.jar添加到項目類路徑中,以添加對@Inject的支持。您也可以嘗試使用spring的本地@Autowired註釋。

+0

謝謝,Maks,inject.jar在那裏。這個項目使用xml配置和註解驅動工作正常。我想看看它如何與3.1並且不能通過這個障礙。一定是想念我無法弄清楚的事情。 – jfd

+0

嗯,我試圖在Spring 3.1上使用@inject和Environment,它工作正常。請顯示你的xml配置,如果可能的話 – maks

+0

你好,麥克斯,我在那裏更新了更多文件的原文。我不知道如何在這裏添加東西。謝謝 – jfd

1

@jfd,

我沒有立即看到什麼不對您的配置會導致失敗注入環境。

如果您從頭開始使用空的@Configuration類,然後@Inject環境,它是否適合您?

如果是,那麼它在什麼時候開始失敗?

您是否願意將該示例縮減到可能失敗的最小配置並將其作爲複製項目提交?這裏的說明使這儘可能簡單:https://github.com/SpringSource/spring-framework-issues#readme

謝謝!

+0

謝謝克里斯。當我剝去一切並逐漸將它們添加回來。我發現secrityConfig.java是導致問題的原因。仍然試圖找出原因。但後來我堅持另一個問題,休眠抱怨「Dialect類未找到:MYSQL」,這是一個非XML問題。所以我猜電動勢/交易部分仍然不正確 – jfd

+0

這太微妙了。我發現如果有一個或所有的postConstruct,我需要在屬性之後調用所有的屬性。真的嗎?我得到的另一件事是一些配置文件加載,一些永遠不會然後他們掃描包,所以不autofire不工作,因爲一些配置文件從未調用。 – jfd

+0

你好克里斯,我認爲這個問題可能與我發現的春季安全有關。 – jfd

2

問題在於記住我功能的彈簧安全。如果我拿這條線<code> <remember-me data-source-ref="dataSource" /> </code>出來。一切正常。如果這一行出現,它會嘗試在其他任何事情之前加載數據庫,並且env從未被注入。

1

我已經爲here提及我的項目檢測到類似的錯誤。 我也弄清楚,調用afterproperties是獲取sessionFactory所必需的。 ...是的,我也使用Spring Security(這可能是問題的根源)。

我的@Configuration註釋類使用@ComponentScan包含包含基於Hibernate的DAO的包和一個用於創建DAO使用的SessionFactory的@Bean註解方法。在運行時,拋出異常,提到沒有找到'sessionFactory'或'hibernateTemplate'。看起來DAO是在SessionFactory創建之前構建的。對我來說一個解決方法是將組件掃描指令放回到XML文件()中,並用該文件的@ImportResource替換@ComponentScan。另一個有趣的事實是:如果包含@ComponentScan,則在方法sessionFactory()中設置的斷點永遠不會到達!

+0

我通過將配置文件僅用於掃描並加載最後一個(使用@Import(xxx.class))來傳遞該問題。移動到java配置時需要注意很多:1)afterproperty或postconstruct函數調用; 2)除字符串以外的枚舉和類路徑資源; 3)舊物業方式以外的環境物品等等,有些物品應該像春天的物業一樣在春季機械中處理。 – jfd

1

我也有類似的問題與春季社會示例應用程序。

我將字段級別@Inject轉換爲構造函數級別之後注入它的工作。

5

不知道爲什麼,但使用@Resource註釋爲我工作。 @Autowired總是返回null。