Spring 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没有被注入并且始终为null。

我没有对环境设置做任何事情,因为我不知道它是否需要或如何。 我看了温室的例子,我没有找到任何专门针对环境的东西。 我该怎么做以确保注入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中,它只导入了两个xmls来配置缓存和cassandra,因此它可能并不重要。

不知道为什么,但使用@Resource注释为我工作。 @Autowired总是返回null。

问题在于记住我function的弹簧安全性。 如果我把这行 取出来。 一切正常。 如果这一行显示,它将尝试在其他任何东西之前加载db并且从未注入env。

如果不使用完整的Java EE兼容服务器,则必须在项目类路径中包含javax.inject.jar以添加对@Inject的支持。 您还可以尝试使用spring的原生@Autowired注释。

@jfd,

我没有立即发现您的配置有任何错误会导致无法注入环境。

如果您从头开始使用空的@Configuration类,然后@Inject the Environment,它是否适合您?

如果是,那么它在什么时候开始失败?

您是否愿意将示例缩小到失败的最小可能配置并将其作为复制项目提交? 这里的说明使这个变得尽可能简单: https : //github.com/SpringSource/spring-framework-issues#readme

谢谢!

我在这里提到的项目中检测到类似的错误。 我还想知道,调用afterproperties是获得sessionFactory所必需的。 …是的,我也在使用Spring Security(这可能是问题的根源)。

我的@Configuration注释类将@ComponentScan用于包含基于Hibernate的DAO的包和用于创建DAO使用的SessionFactory的@Bean注释方法。 在运行时,抛出一个exception,提到找不到’sessionFactory’或’hibernateTemplate’。 似乎在创建SessionFactory之前构造了DAO。 我的一个解决方法是将组件扫描指令放回XML文件()中,并将@ComponentScan替换为该文件的@ImportResource。

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

同样有趣的事实是:如果包含@ComponentScan,则永远不会在方法sessionFactory()中设置断点!

我也遇到过与spring-social-sample app类似的问题。

在我将字段级别@Inject转换为构造函数级别后,它已经工作了。