使用PropertySourcesPlaceholderConfigurer在多个上下文中创建Spring属性
好吧,我已经为此奋斗太久了,是时候寻求帮助了。救命啊?! 我无法使用PropertySourcesPlaceholderConfigurer使我的属性在某个上下文中工作 我有两个上下文: 根上下文:使用PropertySourcesPlaceholderConfigurer在多个上下文中创建Spring属性,spring,spring-mvc,properties,Spring,Spring Mvc,Properties,好吧,我已经为此奋斗太久了,是时候寻求帮助了。救命啊?! 我无法使用PropertySourcesPlaceholderConfigurer使我的属性在某个上下文中工作 我有两个上下文: 根上下文: AnnotationConfigWebApplicationContext rootContext = createContext(InfrastructureContextConfiguration.class); 还有一个dispatcherContext: AnnotationConfigW
AnnotationConfigWebApplicationContext rootContext = createContext(InfrastructureContextConfiguration.class);
还有一个dispatcherContext:
AnnotationConfigWebApplicationContext dispatcherContext = createContext(WebMvcContextConfiguration.class);
这些将按如下方式加载:
public class MyWebApplicationInitializer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
registerListener(servletContext);
registerDispatcherServlet(servletContext);
}
private void registerDispatcherServlet(ServletContext servletContext) {
AnnotationConfigWebApplicationContext dispatcherContext = createContext(WebMvcContextConfiguration.class, WebFlowContextConfiguration.class);
ServletRegistration.Dynamic dispatcher = servletContext.addServlet(DISPATCHER_SERVLET_NAME, new DispatcherServlet(dispatcherContext));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/");
}
private void registerListener(ServletContext servletContext) {
AnnotationConfigWebApplicationContext rootContext = createContext(InfrastructureContextConfiguration.class );
servletContext.addListener(new ContextLoaderListener(rootContext));
servletContext.addListener(new RequestContextListener());
}
我创建PropertySourcesPlaceholderConfigurer并在dispatcherContext WebMvcContextConfiguration中设置@PropertySource:
@Configuration
@EnableWebMvc
@PropertySource("classpath:my.properties")
@ComponentScan(basePackages = { "com.me.my.web" })
public class WebMvcContextConfiguration extends WebMvcConfigurerAdapter {
@Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
}
因此,您可以使用以下方式访问此dispatcherContext中的属性:
@Value( "${recaptcha.private.key}" )
private String recaptchaPrivateKey;
问题是我无法从我的根上下文访问这些属性。我尝试了@value注释。我试图在InfrastructureContextConfiguration类中创建第二个PropertySourcesPlaceHolderConfigurer,呃
@Configuration
@EnableTransactionManagement
@PropertySource("classpath:my.properties")
@ComponentScan(basePackages = { "com.me.my.service", "com.me.my.repository",
"com.me.my.domain.support" })
public class InfrastructureContextConfiguration {
//load properties from my.properties file
@Value( "${mysql.db.driver.class}" ) //this is always null!
private String mysqlDriverClass ;
...
}
@Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
@Bean
public DataSource dataSource() {
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName(mysqlDriverClass);
...
}
...
}
更新:我在InfrastructureContextConfiguration中添加了一个PropertySourcesPlaceHolderConfigurer和@PropertySource(“classpath:my.properties”)。我在上面更改了这个类以反映我的更改。通过使用调试器逐步执行InfrastructureContextConfiguration,我最初看到任何注入的属性都为null,但最终它们都有值。例如,在Datasource Datasource()方法中,“mysqlDriverClass”为null,因此这会失败,但稍后在这个类中,其他bean是使用其他具有良好/非null值的注入属性构造的。在什么时候我可以安全地尝试访问这些属性值
回答我的更新我解决了我的问题。我在@Value注入属性之前声明了@Autowired DataSource成员变量,因此在解析注入属性之前,数据源由类初始化。如@Patouche所述,在根应用程序上下文中定义的bean在所有web应用程序上下文中都是可访问的,但反过来就不行了 每个DispatcherServlet都有一个从根web应用程序上下文继承的关联web应用程序上下文。如果您需要根web应用程序上下文中的值或bean,那么您必须在那里定义它
有关更多信息,请参阅本讨论。它还有一个到相关Spring文档的链接 我对你的问题并不感到惊讶。您可以有多个web上下文,但始终只有一个根上下文。web上下文不会与其他上下文共享它们的属性。例如,您可以为每个web上下文定义两个属性
recaptcha.private.key
。哪一个应该成为您的根上下文?我认为最好的方法是在InfrastructureContextConfiguration
中定义另一个@PropertySource
,以正确注入您的。谢谢,这非常有帮助。