让 Spring PropertyPlaceholderConfigurer 覆盖 MessageSource 值的问题

发布于 2024-10-11 09:58:40 字数 4217 浏览 0 评论 0原文

我有 spring Java 配置对象,它加载我的属性但不会覆盖 MessageSource 令牌。

@Configuration
@SuppressWarnings("unused")
public class PropertyConfiguration {

public static final String PROPERTY_OVERRIDE_URL = "d2.config.location";

@Bean
public UrlResource propertyOverrideUrl() {
    String propertyOverrideUrl = System.getProperty(PROPERTY_OVERRIDE_URL);

    UrlResource overrideUrl = null;
    // just add a bogus url as to not get a malformed URL
    try{
        overrideUrl = new UrlResource(
                (propertyOverrideUrl == null || "".equals(propertyOverrideUrl)? "file:///FILENOTFOUND" : propertyOverrideUrl)
        );
    } catch (MalformedURLException e){
        // Set the URL to a dummy value so it will not break.
        try{
            overrideUrl = new UrlResource("file:///FILENOTFOUND");
        } catch (MalformedURLException me){
            // this is a valid URL, but will not be found at runtime.
        }
    }
    return overrideUrl;
}

@Bean
@DependsOn("propertyOverrideUrl")
@Lazy(false)
public ContextAwarePropertyPlaceholderConfigurer propertyPlaceholderConfigurer()
throws IOException{
    return new ContextAwarePropertyPlaceholderConfigurer(){{
        setLocations(new Resource[]{
            new ClassPathResource("application_prompts.properties"),
            new ClassPathResource("application_webservice.properties"),
            new ClassPathResource("application_externalApps.properties"),
            new ClassPathResource("application_log4j.properties"),
            new ClassPathResource("application_fileupload.properties"),
            //Must be last to override all other resources
            propertyOverrideUrl()
        });
        setIgnoreResourceNotFound(true);
    }};
}

当我对 javaconfig 属性运行单元测试时,情况很好:

    @Test
public void testOverrides__Found() throws Exception {
    setOverrideUrlSystemProperty("/target/test/resources/override-test.properties");
    context = SpringContextConfigurationTestHelper.createContext();
    context.refresh();

    String recordedPaymentConfirmationPath =
            (String)context.getBean("recordedPaymentConfirmationPath");
    assertThat(recordedPaymentConfirmationPath, is("test/dir/recordings/"));

    String promptServerUrl =
            (String)context.getBean("promptServerUrl");
    assertThat(promptServerUrl, is("http://test.url.com"));
}

但是当我尝试 MessageSource 的值时,它仍然具有旧值:

    @Test
public void testOverrides__XYZ() throws Exception {
    setOverrideUrlSystemProperty("/target/test/resources/override-test.properties");
    context = SpringContextConfigurationTestHelper.createContext();
    context.refresh();

    String promptServerUrl = (String)context.getMessage("uivr.prompt.server.url",
                    new Object[] {}, Locale.US);

    assertThat(promptServerUrl, is("http://test.url.com"));
}

输出:

[junit] Testcase: testOverrides__XYZ took 0.984 sec
[junit]     FAILED
[junit]
[junit] Expected: is "http://test.url.com"
[junit]      got: "http://24.40.46.66:9010/agent-ivr-prompts/"
[junit]
[junit] junit.framework.AssertionFailedError:
[junit] Expected: is "http://test.url.com"
[junit]      got: "http://24.40.46.66:9010/agent-ivr-prompts/"
[junit]
[junit]     at     com.comcast.ivr.agent.configuration.PropertyOverrideConfigurationTest.testOverrides__XYZ(PropertyOverrideConfigurationTest.java:114)

有人可以帮我找到一种覆盖 MessageSource 的方法吗?在我们的速度模板中使用:

    #set($baseUrl = "#springMessage('uivr.prompt.server.url')")

我添加了一些日志记录:

  @Override
  protected void loadProperties(Properties props) throws IOException {
    super.loadProperties(props);
    super.mergeProperties();
    if(logger.isDebugEnabled()){
        System.out.println("--------------------");
        for (Map.Entry entry : props.entrySet()) {
            System.out.println(entry.getKey() + ":" + entry.getValue());
            logger.info(entry.getKey() + ":" + entry.getValue());
        }
        System.out.println("--------------------");
    }
}

并且值按预期打印。

...
[junit] uivr.prompt.server.url:http://test.url.com
...

I have spring Java config object that loads my properties but does not override the MessageSource tokens.

@Configuration
@SuppressWarnings("unused")
public class PropertyConfiguration {

public static final String PROPERTY_OVERRIDE_URL = "d2.config.location";

@Bean
public UrlResource propertyOverrideUrl() {
    String propertyOverrideUrl = System.getProperty(PROPERTY_OVERRIDE_URL);

    UrlResource overrideUrl = null;
    // just add a bogus url as to not get a malformed URL
    try{
        overrideUrl = new UrlResource(
                (propertyOverrideUrl == null || "".equals(propertyOverrideUrl)? "file:///FILENOTFOUND" : propertyOverrideUrl)
        );
    } catch (MalformedURLException e){
        // Set the URL to a dummy value so it will not break.
        try{
            overrideUrl = new UrlResource("file:///FILENOTFOUND");
        } catch (MalformedURLException me){
            // this is a valid URL, but will not be found at runtime.
        }
    }
    return overrideUrl;
}

@Bean
@DependsOn("propertyOverrideUrl")
@Lazy(false)
public ContextAwarePropertyPlaceholderConfigurer propertyPlaceholderConfigurer()
throws IOException{
    return new ContextAwarePropertyPlaceholderConfigurer(){{
        setLocations(new Resource[]{
            new ClassPathResource("application_prompts.properties"),
            new ClassPathResource("application_webservice.properties"),
            new ClassPathResource("application_externalApps.properties"),
            new ClassPathResource("application_log4j.properties"),
            new ClassPathResource("application_fileupload.properties"),
            //Must be last to override all other resources
            propertyOverrideUrl()
        });
        setIgnoreResourceNotFound(true);
    }};
}

When I run a unit test on the javaconfig property it is fine:

    @Test
public void testOverrides__Found() throws Exception {
    setOverrideUrlSystemProperty("/target/test/resources/override-test.properties");
    context = SpringContextConfigurationTestHelper.createContext();
    context.refresh();

    String recordedPaymentConfirmationPath =
            (String)context.getBean("recordedPaymentConfirmationPath");
    assertThat(recordedPaymentConfirmationPath, is("test/dir/recordings/"));

    String promptServerUrl =
            (String)context.getBean("promptServerUrl");
    assertThat(promptServerUrl, is("http://test.url.com"));
}

But when I try the value of the MessageSource, it still has the old value:

    @Test
public void testOverrides__XYZ() throws Exception {
    setOverrideUrlSystemProperty("/target/test/resources/override-test.properties");
    context = SpringContextConfigurationTestHelper.createContext();
    context.refresh();

    String promptServerUrl = (String)context.getMessage("uivr.prompt.server.url",
                    new Object[] {}, Locale.US);

    assertThat(promptServerUrl, is("http://test.url.com"));
}

The output:

[junit] Testcase: testOverrides__XYZ took 0.984 sec
[junit]     FAILED
[junit]
[junit] Expected: is "http://test.url.com"
[junit]      got: "http://24.40.46.66:9010/agent-ivr-prompts/"
[junit]
[junit] junit.framework.AssertionFailedError:
[junit] Expected: is "http://test.url.com"
[junit]      got: "http://24.40.46.66:9010/agent-ivr-prompts/"
[junit]
[junit]     at     com.comcast.ivr.agent.configuration.PropertyOverrideConfigurationTest.testOverrides__XYZ(PropertyOverrideConfigurationTest.java:114)

Can someone please help me find a way to override the MessageSource because that is what is used in our velocity templates:

    #set($baseUrl = "#springMessage('uivr.prompt.server.url')")

I added some logging:

  @Override
  protected void loadProperties(Properties props) throws IOException {
    super.loadProperties(props);
    super.mergeProperties();
    if(logger.isDebugEnabled()){
        System.out.println("--------------------");
        for (Map.Entry entry : props.entrySet()) {
            System.out.println(entry.getKey() + ":" + entry.getValue());
            logger.info(entry.getKey() + ":" + entry.getValue());
        }
        System.out.println("--------------------");
    }
}

And the values are printed as expected.

...
[junit] uivr.prompt.server.url:http://test.url.com
...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

请持续率性 2024-10-18 09:58:40

关于 propertyPlaceholderConfigurer() @Bean 方法上使用的注释的一些旁注:

  • @Lazy(false) 是不必要的,因为它已经是默认值。你可以省略这个。
  • propertyPlaceholderConfigurer() 中调用 propertyOverrideUrl() 来建立依赖关系

@DependsOn("propertyOverrideUrl") 是不必要的,因为已经通过 您的实际问题,有点难以回答,因为我不确定 ContextAwareProperyPlaceholderConfigurer 是做什么的(我假设它是一个自定义组件,因为它不是核心 Spring 框架的一部分)。

除此之外,可能只是存在误解。 Spring 的 PropertyPlaceholderConfigurer (PPC) 和朋友通过后处理 bean 定义来替换 ${...} 占位符,但不与 MessageSource 交互代码>对象以任何方式。因此,我相信您描述的行为符合预期:在询问 bean 时您会看到“正确”的 URL(因为它已由您的 PPC 进行后处理),但是在询问消息时您会看到“不正确”的 url来源(因为它与PPC后处理完全无关)。

希望这有帮助。

A couple side notes about the annotations used on your propertyPlaceholderConfigurer() @Bean method:

  • @Lazy(false) is unnecessary, as it is already the default. You can omit this.
  • @DependsOn("propertyOverrideUrl") is unnecessary, because the dependency is already established by calling propertyOverrideUrl() from within the propertyPlaceholderConfigurer()

On to your actual question, it's a bit tough to answer because I'm not sure what ContextAwareProperyPlaceholderConfigurer does (I'm assuming it's a custom component as it's not part of the core Spring Framework).

That aside, there may simply be a misunderstanding going on. Spring's PropertyPlaceholderConfigurer (PPC) and friends operate by post-processing bean definitions to replace ${...} placeholders, but don't interact with MessageSource objects in any way. So the behavior you describe is, I believe, as expected: You would see the 'correct' URL when interrogating the bean (because it has been post-processed by your PPC), however you see the 'incorrect' url when interrogating the message source (because it is totally unrelated to PPC post-processing).

Hope this helps.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文