【问题标题】:Resolving placeholder within @PropertySource解析@PropertySource 中的占位符
【发布时间】:2015-06-10 18:31:55
【问题描述】:

我正在尝试创建一个配置类,该类将使用 @PropertySource 注释从文件中加载应用程序属性,但 PropertySourcesPlaceholderConfigurer 似乎没有设置从注释接收到的位置。

@Configuration
@ComponentScan("com.just.a.test")
@PropertySources({
    @PropertySource(value="file:C:\\tmp\\1.cfg" 
            , ignoreResourceNotFound=true)
})
public class TestConfig {
    @Value("${just.a.string}")
    String justAString;


    @Bean
    public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
        PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer = new PropertySourcesPlaceholderConfigurer();
       return propertySourcesPlaceholderConfigurer;
    }
}

应用程序属性文件是:

just.a.string=DOH

我收到以下异常:

.... 原因:java.lang.IllegalArgumentException:无法解析字符串值“${just.a.string}”中的占位符“just.a.string”
在 org.springframework.util.PropertyPlaceholderHelper.parseStringValue(PropertyPlaceholderHelper.java:174)
在 org.springframework.util.PropertyPlaceholderHelper.replacePlaceholders(PropertyPlaceholderHelper.java:126)
在 org.springframework.core.env.AbstractPropertyResolver.doResolvePlaceholders(AbstractPropertyResolver.java:204)
在 org.springframework.core.env.AbstractPropertyResolver.resolveRequiredPlaceholders(AbstractPropertyResolver.java:178)
在 org.springframework.context.support.PropertySourcesPlaceholderConfigurer$2.resolveStringValue(PropertySourcesPlaceholderConfigurer.java:175)
在 org.springframework.beans.factory.support.AbstractBeanFactory.resolveEmbeddedValue(AbstractBeanFactory.java:801)
在 org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:955)
在 org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:942)
在 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:533)
... 15 更多

但是,如果我使用 PropertySourcesPlaceholderConfigurer bean 设置位置,一切正常。

@Bean
    public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
        PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer = new PropertySourcesPlaceholderConfigurer();
propertySourcesPlaceholderConfigurer.setLocation(new FileSystemResource("c:\\tmp\\1.cfg"));
       return propertySourcesPlaceholderConfigurer;
    }

我正在使用 Spring 4.1.6-RELEASE 和 jdk 8.05。

提前致谢。

更新 1

正如 sivaprasadreddy.k 提到的。上面的代码工作正常,我忘记了在我的原始代码中,我正在使用 -

从 JVM 参数中检索文件
@PropertySource(value="file:#{systemProperties['config.path']}" 

并传递一个 jvm 参数:

-Dconfig.path=C:\\tmp\\1.cfg

@Sotirios - 我只是像这样使用 AnnotationConfigApplicationContext(Class) -

public static void main(String[] args) { 
new AnnotationConfigApplicationContext(TestConfig.class);
 }

更新 2

基本上我想要实现的是:

1) 使用名称定义为 const 的 jvm 参数加载属性文件

a) 如果找到文件,则继续

b) 否则,如果存在定义为 const 的默认文件路径,则继续

c) 否则继续。

2) 尝试使用名称定义为 const 的属性解析 @Value

a) 如果找到继续

b) 否则使用 const 加载默认值。

对不起,空格。编辑器出了点问题。

【问题讨论】:

  • 你能展示一下你是如何加载你的TestConfig的吗?
  • 你能把ignoreResourceNotFound=true去掉,看看是否尝试加载资源?
  • 我使用了您的代码 sn-ps 并使用 Spring-4.1.6 和 JDK 8 进行了测试,并且工作正常。如果我输出 justAString 值,它正在解析并打印“DOH”。
  • @Sotirios - 我只是像这样使用 AnnotationConfigApplicationContext(Class) - public static void main(String[] args) { new AnnotationConfigApplicationContext(TestConfig.class); }
  • 这对我有用。你能提供一个完整且可重复的例子吗?

标签: java spring


【解决方案1】:

考虑您的编辑

@PropertySource(value="file:#{systemProperties['config.path']}" 

您必须首先意识到 @Configuration 类(及其注释)在其内部声明的 @Bean 之前被解析和处理。换句话说,在 Spring 处理 @PropertySource 注释时,您的 PropertySourcesPlaceholderConfig (解析 #{..} 占位符)尚未注册。不可用。

相反,Spring 可以执行PropertySourcesPlaceholderConfig 提供的行为的子集,只有${..} 占位符。 (See the javadoc.) 而且它只能使用已经注册到你的ApplicationContextEnvironment的属性源。在您的示例中,(应该)只有两个来源,系统属性和系统环境。

符号

systemProperties['config.path']

声明:在名为systemProperties 的属性源中给我属性config.path 的值。我不确定 Spring 检查上述属性源的顺序,但如果您知道只有您的系统属性(而不是环境)具有 config.path 属性,您可以简单地使用

@PropertySources(value = { @PropertySource(value = "file:${config.path}") })

【讨论】:

  • 感谢 Sotirios。使用 ${..} 我现在可以成功地将文件加载到 PropertySourcesPlaceholderConfig 并解析值 ${just.a.string}。我看到文件在 PropertySourcesPlaceholderConfig.environment.propertySources=[systemProperties,systemEnvironment,URL [file:C://tmp//1.cfg]]} 我仍然无法使用 #{..} .
  • Spring 不处理 @PropertySource 值中以 #{ 开头的占位符。
  • 我的意思是在@Value 中我仍然无法加载我使用@PropertySource(${config.path}) 加载的属性
  • @Value("#{systemProperties['just.a.string']}") = null ,
  • @TalBenShabtay 您的系统属性中有一个名为just.a.string 的属性吗?还是在您加载的属性文件中?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-11-01
  • 2019-03-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-15
  • 2017-07-23
相关资源
最近更新 更多