好的,我一直在争取这么长时间,是时候寻求帮助了。救命?! 我无法使用PropertySourcesPlaceholderConfigurer使我的属性在我的某个上下文中工作。
我有2个背景: rootContext:
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我最初看到任何注入的属性为null但最终它们具有值。例如,在Datasource dataSource()方法中," mysqlDriverClass"为null因此失败但稍后在此类中使用具有良好/非空值的其他注入属性构造其他bean。我可以在什么时候安全地尝试访问这些属性值?
回答我的更新我发现了我的问题。我在@Value注入属性之前声明@Autowired DataSource成员变量,因此在注入属性被解析之前,类正在初始化dataSource。
答案 0 :(得分:1)
正如@Patouche所提到的,在根应用程序上下文中定义的bean可以在所有Web应用程序上下文中访问,但它没有相反的工作方式。
每个DispatcherServlet都有一个关联的web applicationContext,它继承自根Web应用程序上下文。如果您需要在根Web应用程序上下文中使用值或bean,那么您必须在那里定义它。
有关详细信息,请参阅此讨论。它还有一个指向相关Spring文档的链接。 Spring root WebApplicationContext for Servlet