Spring 3.1配置:环境未注入
我在 spring 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中,它只导入了两个xml来配置缓存和cassandra,所以它可能并不重要。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
我在 spring-social-sample 应用程序中也遇到了类似的问题。
在我将字段级别 @Inject 转换为构造函数级别注入后,它起作用了。
I also had the similar issue with spring-social-sample app.
After I converted field level @Inject to constructor level inject it worked.
@jfd,
我没有立即发现您的配置有任何问题,会导致注入环境失败。
如果您从头开始使用一个空的 @Configuration 类,然后 @Inject 环境,它对您有用吗?
如果是,那么它在什么时候开始失败?
您愿意将示例减少到可能失败的最小配置并将其作为复制项目提交吗?这里的说明使这尽可能简单: https://github.com/SpringSource/spring -framework-issues#readme
谢谢!
@jfd,
I don't immediately see anything wrong with your configuration that would cause a failure to inject the Environment.
If you start from scratch with an empty @Configuration class, and then @Inject the Environment, does it work for you?
If yes, then at what point does it begin to fail?
Would you be willing to reduce the example down to the smallest possible configuration that fails and submit it as a reproduction project? The instructions here make this as simple as possible: https://github.com/SpringSource/spring-framework-issues#readme
Thanks!
我在我的项目中检测到类似的错误,如上所述 此处。
我还发现,需要调用 afterproperties 才能获取 sessionFactory。
...是的,我也在使用 Spring Security(这可能是问题的根源)。
我的 @Configuration 带注释的类对包含基于 Hibernate 的 DAO 的包使用 @ComponentScan,并使用 @Bean 带注释的方法来创建 DAO 使用的 SessionFactory。在运行时,抛出异常,提到未找到“sessionFactory”或“hibernateTemplate”。看起来 DAO 是在创建 SessionFactory 之前构建的。对我来说,一种解决方法是将组件扫描指令放回 XML 文件 () 中,并将 @ComponentScan 替换为该文件的 @ImportResource。
另外有趣的事实是:如果包含 @ComponentScan,则永远不会到达方法 sessionFactory() 中设置的断点!
I've detect a similar error for my project as mentioned here.
I've also figure out, that a call of afterproperties is necessary to get the sessionFactory.
... and yes, I'm using Spring Security too (which may be the source of the problem).
My @Configuration annotated class uses @ComponentScan for packages containing Hibernate based DAOs and a @Bean annotated method for creating the SessionFactory used by the DAOs. At runtime, a exception is thrown, mentioned that 'sessionFactory' or 'hibernateTemplate' was not found. It seems that the DAOs are constructed before the SessionFactory was created. One workaround for me was to put the component scan directive back in a XML file () and replace @ComponentScan with @ImportResource of that file.
Also interesting fact: if @ComponentScan is included, a breakpoint set in method sessionFactory() was never reached !
问题在于 spring security 的“记住我”功能。如果我采取这一行
输出。一切正常。如果出现此行,它将尝试在执行其他操作之前加载数据库,并且 env 从未被注入。;>
The problem is with the spring security for the remember me feature. if I take this line
<code> <remember-me data-source-ref="dataSource" /> </code>
out. everything works fine. if this line presents, it will try to load the db before anything else and env was never injected.如果您不使用完整的 Java EE 兼容服务器,则必须将 javax.inject.jar 包含到项目类路径中以添加对 @Inject 的支持。你也可以尝试使用spring原生的
@Autowired
注解。If you don't use full Java EE compatible server you have to include
javax.inject.jar
to your project classpath to add the support of@Inject
. You can also try to use spring's native@Autowired
annotation.不知道为什么,但使用 @Resource 注释有效为我。 @Autowired 总是返回 null。
Not sure why, but using the @Resource annotation worked for me. @Autowired always returned null.