【发布时间】:2015-01-13 07:33:28
【问题描述】:
好吧,我已经打了太久了,是时候寻求帮助了。帮助?! 我无法使用 PropertySourcesPlaceholderConfigurer 让我的属性在我的一个上下文中工作。
我有两种情况: 一个根上下文:
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;
问题是我无法从我的 rootContext 访问这些属性。我已经尝试过@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);
...
}
...
}
更新:我已将 PropertySourcesPlaceHolderConfigurer 和 @PropertySource("classpath:my.properties") 添加到我的 InfrastructureContextConfiguration。我在上面更改了这个类以反映我的更改。使用调试器单步执行 InfrastructureContextConfiguration 我最初看到任何注入的属性都是空的,但最终它们都有值。例如,在 Datasource dataSource() 方法中,“mysqlDriverClass”为空,因此失败,但稍后在此类中,其他 bean 由其他注入的具有良好/非空值的属性构造。在什么时候我可以安全地尝试访问这些属性值?
回答我的更新我发现了我的问题。我在@Value 注入属性之前声明了@Autowired DataSource 成员变量,因此在解析注入属性之前,该类正在初始化数据源。
【问题讨论】:
-
我对你的问题并不感到惊讶。您可以拥有多个 Web 上下文,但始终只有一个根上下文。 Web 上下文不会与另一个上下文共享它们的属性。例如,您可以为每个 Web 上下文定义 2 个属性
recaptcha.private.key。哪一个应该成为你的根源?我认为最适合您的是在您的InfrastructureContextConfiguration中定义另一个@PropertySource以正确注入。 -
谢谢,这很有帮助。
标签: spring spring-mvc properties