我已经看过类似的问题并尝试了很多变体,想出了应该工作但仍然有NullPointerException的东西。这是一个Web应用程序,这是我的AppListener的contextInitialized():
AnnotationConfigWebApplicationContext wac = new AnnotationConfigWebApplicationContext();
wac.setServletContext(sc);
wac.setParent(rootContext);
propertySourcesPlaceholderConfigurer = new PropertySourcesPlaceholderConfigurer();
propertySourcesPlaceholderConfigurer.setLocation(new PathResource(_configFile)); // yes it's dynamic
wac.addBeanFactoryPostProcessor(propertySourcesPlaceholderConfigurer);
wac.register(Configuration.class);
sc.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac);
//TODO check if works properly - security. didn't manage to keep it in the same config class
wac.register(SecurityConfiguration.class);
wac.refresh();
这是我的配置类(Configuration.class):
@Autowired //(used to be @Inject, no difference)
private Environment env;
@Bean
public MessageSource messageSource(){
ReloadableResourceBundleMessageSource ms = new ReloadableResourceBundleMessageSource();
ms.addBasenames(new String[]{
env.getProperty("paths.appConfigDir") + "/i18n/message",
env.getProperty("paths.defaultConfigDir") + "/i18n/message"
});
ms.setDefaultEncoding("UTF-8");
return ms;
}
env为null,因此是NPE。
我做错了什么?
什么是现代方法,将文件中的属性加载到占位符和环境中,在启动时评估属性文件名(基本上,从另一个配置文件中获取)?
我的应用程序上下文mehtods调用应该是什么顺序? (猜猜这是我的错误)
添加 让我另外强调属性文件名是变量
更新 正确的答案标记如下:不要做奇怪的事情,否则你将面临一些陷阱。
虽然答案和建议是正确的,但由于其他原因,我作为一个没有经验的Spring用户不知道值得包含在问题中,这对我没有帮助。基本上,我已经得到了我的问题的答案,但我无法遵循建议,不得不深入调试事情,并发现如果你遵循我的路线你可能会考虑以下两个项目:
配置类过早实例化,因此缺少注入的环境,因为:
1)不要将配置类称为“配置”。在初始化阶段,Spring Web中的某些东西尝试获取名为“configuration”的bean,看到这个类并实例化它。
2)将messageSource bean移动到父上下文,因为它是在Spring Web初始化中尽早寻找的;在messageSource bean方法中查询环境似乎是不可能的,还没有环境。
希望这有帮助。
答案 0 :(得分:0)
在Configuration类中添加以下提到的注释:
1. @PropertySource
工作代码如下:
@Configuration
@PropertySource("classpath:your-property-file.properties")
public class Config {
@Autowired
private Environment env;
@Bean(name="testSource")
public MessageSource messageSource(){
ReloadableResourceBundleMessageSource ms = new ReloadableResourceBundleMessageSource();
ms.addBasenames(new String[]{
env.getProperty("paths.appConfigDir") + "/i18n/message",
env.getProperty("paths.defaultConfigDir") + "/i18n/message"
});
ms.setDefaultEncoding("UTF-8");
return ms;
}
}
答案 1 :(得分:0)
要修改PropertySource
使用的Environment
个实例,请使用ApplicationContextInitializer
。这允许您在实际创建PropertySource
之前添加ApplicationContext
个实例。
public class YourApplicationContextInitializer implements ApplicationContextInitializer {
public void initialize(ConfigurableApplicationContext context) {
Resource resource = new PathResource(_configFile);
ConfigurableEnvironment env = context.getEnvironment();
MutablePropertySources mps = env.getPropertySources();
mps.addFirst(new ResourcePropertySource("config-file", resource));
}
}
此课程会将您已配置的PathResource
添加为PropertySource
中的第一个Environment
,并且也可能已被可用的PropertySourcesPlaceholderConfigurer
使用。
假设您有WebApplicationInitializer
扩展AbstractAnnotationConfigDispatcherServletInitializer
实现getRootApplicationContextInitializers
和getServletApplicationContextInitializers
以返回此类的实例。
public class YourWebApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
// Your other init code here
protected ApplicationContextInitializer<?>[] getServletApplicationContextInitializers() {
return new ApplicationContextInitializer[] { new YourApplicationContextInitializer()};
}
protected ApplicationContextInitializer<?>[] getRootApplicationContextInitializers() {
return new ApplicationContextInitializer[] { new YourApplicationContextInitializer()};
}
}
getRootApplicationContextInitializers
将为ApplictionContexInitializer
ContextLoaderListener
加载的上下文添加getServletApplicationContextInitializers
DispatcherServlet
将对id subject date
1 MCA 2/5/2010
1 BSC SCIENCE 5/8/1997
2 BTECH 8/9/1999
3 BTECH 8/6/2000
3 MTECH 6/7/2014
执行相同操作。