Polish 'Allow common messages to be specified for message sources'
See gh-42472
This commit is contained in:
parent
573ccc5007
commit
06569af789
|
@ -19,6 +19,7 @@ package org.springframework.boot.autoconfigure.context;
|
|||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.time.Duration;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.springframework.aot.hint.RuntimeHints;
|
||||
|
@ -41,6 +42,7 @@ import org.springframework.context.annotation.Conditional;
|
|||
import org.springframework.context.annotation.ImportRuntimeHints;
|
||||
import org.springframework.context.support.AbstractApplicationContext;
|
||||
import org.springframework.context.support.ResourceBundleMessageSource;
|
||||
import org.springframework.core.CollectionFactory;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
|
||||
|
@ -85,20 +87,24 @@ public class MessageSourceAutoConfiguration {
|
|||
}
|
||||
messageSource.setAlwaysUseMessageFormat(properties.isAlwaysUseMessageFormat());
|
||||
messageSource.setUseCodeAsDefaultMessage(properties.isUseCodeAsDefaultMessage());
|
||||
messageSource.setCommonMessages(loadCommonMessages(properties.getCommonMessages()));
|
||||
return messageSource;
|
||||
}
|
||||
|
||||
try {
|
||||
if (properties.getCommonMessages() != null) {
|
||||
Properties commonProperties = new Properties();
|
||||
for (Resource commonResource : properties.getCommonMessages()) {
|
||||
PropertiesLoaderUtils.fillProperties(commonProperties, commonResource);
|
||||
}
|
||||
messageSource.setCommonMessages(commonProperties);
|
||||
private Properties loadCommonMessages(List<Resource> resources) {
|
||||
if (CollectionUtils.isEmpty(resources)) {
|
||||
return null;
|
||||
}
|
||||
Properties properties = CollectionFactory.createSortedProperties(false);
|
||||
for (Resource resource : resources) {
|
||||
try {
|
||||
PropertiesLoaderUtils.fillProperties(properties, resource);
|
||||
}
|
||||
catch (IOException ex) {
|
||||
throw new UncheckedIOException("Failed to load common messages from '%s'".formatted(resource), ex);
|
||||
}
|
||||
}
|
||||
catch (IOException ex) {
|
||||
throw new UncheckedIOException("Failed to load common messages", ex);
|
||||
}
|
||||
return messageSource;
|
||||
return properties;
|
||||
}
|
||||
|
||||
protected static class ResourceBundleCondition extends SpringBootCondition {
|
||||
|
|
|
@ -46,7 +46,7 @@ public class MessageSourceProperties {
|
|||
private List<String> basename = new ArrayList<>(List.of("messages"));
|
||||
|
||||
/**
|
||||
* Comma-separated list of locale-independent common messages.
|
||||
* List of locale-independent property file resources containing common messages.
|
||||
*/
|
||||
private List<Resource> commonMessages;
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
* Copyright 2012-2024 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -58,7 +58,7 @@ class MessageSourceAutoConfigurationTests {
|
|||
|
||||
@Test
|
||||
void propertiesBundleWithSlashIsDetected() {
|
||||
this.contextRunner.withPropertyValues("spring.messages.basename:test/messages").run((context) -> {
|
||||
this.contextRunner.withPropertyValues("spring.messages.basename=test/messages").run((context) -> {
|
||||
assertThat(context).hasSingleBean(MessageSource.class);
|
||||
assertThat(context.getMessage("foo", null, "Foo message", Locale.UK)).isEqualTo("bar");
|
||||
});
|
||||
|
@ -66,7 +66,7 @@ class MessageSourceAutoConfigurationTests {
|
|||
|
||||
@Test
|
||||
void propertiesBundleWithDotIsDetected() {
|
||||
this.contextRunner.withPropertyValues("spring.messages.basename:test.messages").run((context) -> {
|
||||
this.contextRunner.withPropertyValues("spring.messages.basename=test.messages").run((context) -> {
|
||||
assertThat(context).hasSingleBean(MessageSource.class);
|
||||
assertThat(context.getMessage("foo", null, "Foo message", Locale.UK)).isEqualTo("bar");
|
||||
});
|
||||
|
@ -74,7 +74,7 @@ class MessageSourceAutoConfigurationTests {
|
|||
|
||||
@Test
|
||||
void testEncodingWorks() {
|
||||
this.contextRunner.withPropertyValues("spring.messages.basename:test/swedish")
|
||||
this.contextRunner.withPropertyValues("spring.messages.basename=test/swedish")
|
||||
.run((context) -> assertThat(context.getMessage("foo", null, "Foo message", Locale.UK))
|
||||
.isEqualTo("Some text with some swedish öäå!"));
|
||||
}
|
||||
|
@ -82,14 +82,14 @@ class MessageSourceAutoConfigurationTests {
|
|||
@Test
|
||||
void testCacheDurationNoUnit() {
|
||||
this.contextRunner
|
||||
.withPropertyValues("spring.messages.basename:test/messages", "spring.messages.cache-duration=10")
|
||||
.withPropertyValues("spring.messages.basename=test/messages", "spring.messages.cache-duration=10")
|
||||
.run(assertCache(10 * 1000));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCacheDurationWithUnit() {
|
||||
this.contextRunner
|
||||
.withPropertyValues("spring.messages.basename:test/messages", "spring.messages.cache-duration=1m")
|
||||
.withPropertyValues("spring.messages.basename=test/messages", "spring.messages.cache-duration=1m")
|
||||
.run(assertCache(60 * 1000));
|
||||
}
|
||||
|
||||
|
@ -102,7 +102,7 @@ class MessageSourceAutoConfigurationTests {
|
|||
|
||||
@Test
|
||||
void testMultipleMessageSourceCreated() {
|
||||
this.contextRunner.withPropertyValues("spring.messages.basename:test/messages,test/messages2")
|
||||
this.contextRunner.withPropertyValues("spring.messages.basename=test/messages,test/messages2")
|
||||
.run((context) -> {
|
||||
assertThat(context.getMessage("foo", null, "Foo message", Locale.UK)).isEqualTo("bar");
|
||||
assertThat(context.getMessage("foo-foo", null, "Foo-Foo message", Locale.UK)).isEqualTo("bar-bar");
|
||||
|
@ -119,14 +119,24 @@ class MessageSourceAutoConfigurationTests {
|
|||
@Test
|
||||
void testCommonMessages() {
|
||||
this.contextRunner
|
||||
.withPropertyValues("spring.messages.basename:test/messages",
|
||||
"spring.messages.common-messages:test/common-messages")
|
||||
.withPropertyValues("spring.messages.basename=test/messages",
|
||||
"spring.messages.common-messages=classpath:test/common-messages.properties")
|
||||
.run((context) -> assertThat(context.getMessage("hello", null, "Hello!", Locale.UK)).isEqualTo("world"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCommonMessagesWhenNotFound() {
|
||||
this.contextRunner
|
||||
.withPropertyValues("spring.messages.basename=test/messages",
|
||||
"spring.messages.common-messages=classpath:test/common-messages-missing.properties")
|
||||
.run((context) -> assertThat(context).getFailure()
|
||||
.hasMessageContaining(
|
||||
"Failed to load common messages from 'class path resource [test/common-messages-missing.properties]'"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFallbackDefault() {
|
||||
this.contextRunner.withPropertyValues("spring.messages.basename:test/messages")
|
||||
this.contextRunner.withPropertyValues("spring.messages.basename=test/messages")
|
||||
.run((context) -> assertThat(context.getBean(MessageSource.class))
|
||||
.hasFieldOrPropertyWithValue("fallbackToSystemLocale", true));
|
||||
}
|
||||
|
@ -134,7 +144,7 @@ class MessageSourceAutoConfigurationTests {
|
|||
@Test
|
||||
void testFallbackTurnOff() {
|
||||
this.contextRunner
|
||||
.withPropertyValues("spring.messages.basename:test/messages",
|
||||
.withPropertyValues("spring.messages.basename=test/messages",
|
||||
"spring.messages.fallback-to-system-locale:false")
|
||||
.run((context) -> assertThat(context.getBean(MessageSource.class))
|
||||
.hasFieldOrPropertyWithValue("fallbackToSystemLocale", false));
|
||||
|
@ -142,7 +152,7 @@ class MessageSourceAutoConfigurationTests {
|
|||
|
||||
@Test
|
||||
void testFormatMessageDefault() {
|
||||
this.contextRunner.withPropertyValues("spring.messages.basename:test/messages")
|
||||
this.contextRunner.withPropertyValues("spring.messages.basename=test/messages")
|
||||
.run((context) -> assertThat(context.getBean(MessageSource.class))
|
||||
.hasFieldOrPropertyWithValue("alwaysUseMessageFormat", false));
|
||||
}
|
||||
|
@ -150,7 +160,7 @@ class MessageSourceAutoConfigurationTests {
|
|||
@Test
|
||||
void testFormatMessageOn() {
|
||||
this.contextRunner
|
||||
.withPropertyValues("spring.messages.basename:test/messages",
|
||||
.withPropertyValues("spring.messages.basename=test/messages",
|
||||
"spring.messages.always-use-message-format:true")
|
||||
.run((context) -> assertThat(context.getBean(MessageSource.class))
|
||||
.hasFieldOrPropertyWithValue("alwaysUseMessageFormat", true));
|
||||
|
@ -158,7 +168,7 @@ class MessageSourceAutoConfigurationTests {
|
|||
|
||||
@Test
|
||||
void testUseCodeAsDefaultMessageDefault() {
|
||||
this.contextRunner.withPropertyValues("spring.messages.basename:test/messages")
|
||||
this.contextRunner.withPropertyValues("spring.messages.basename=test/messages")
|
||||
.run((context) -> assertThat(context.getBean(MessageSource.class))
|
||||
.hasFieldOrPropertyWithValue("useCodeAsDefaultMessage", false));
|
||||
}
|
||||
|
@ -166,8 +176,8 @@ class MessageSourceAutoConfigurationTests {
|
|||
@Test
|
||||
void testUseCodeAsDefaultMessageOn() {
|
||||
this.contextRunner
|
||||
.withPropertyValues("spring.messages.basename:test/messages",
|
||||
"spring.messages.use-code-as-default-message:true")
|
||||
.withPropertyValues("spring.messages.basename=test/messages",
|
||||
"spring.messages.use-code-as-default-message=true")
|
||||
.run((context) -> assertThat(context.getBean(MessageSource.class))
|
||||
.hasFieldOrPropertyWithValue("useCodeAsDefaultMessage", true));
|
||||
}
|
||||
|
@ -181,13 +191,13 @@ class MessageSourceAutoConfigurationTests {
|
|||
@Test
|
||||
void existingMessageSourceInParentIsIgnored() {
|
||||
this.contextRunner.run((parent) -> this.contextRunner.withParent(parent)
|
||||
.withPropertyValues("spring.messages.basename:test/messages")
|
||||
.withPropertyValues("spring.messages.basename=test/messages")
|
||||
.run((context) -> assertThat(context.getMessage("foo", null, "Foo message", Locale.UK)).isEqualTo("bar")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void messageSourceWithNonStandardBeanNameIsIgnored() {
|
||||
this.contextRunner.withPropertyValues("spring.messages.basename:test/messages")
|
||||
this.contextRunner.withPropertyValues("spring.messages.basename=test/messages")
|
||||
.withUserConfiguration(CustomBeanNameMessageSourceConfiguration.class)
|
||||
.run((context) -> assertThat(context.getMessage("foo", null, Locale.US)).isEqualTo("bar"));
|
||||
}
|
||||
|
|
|
@ -14,10 +14,12 @@ The basename of the resource bundle as well as several other attributes can be c
|
|||
----
|
||||
spring:
|
||||
messages:
|
||||
basename: "messages,config.i18n.messages"
|
||||
basename: "messages, config.i18n.messages"
|
||||
common-messages: "classpath:my-common-messages.properties"
|
||||
fallback-to-system-locale: false
|
||||
----
|
||||
|
||||
TIP: `spring.messages.basename` supports comma-separated list of locations, either a package qualifier or a resource resolved from the classpath root.
|
||||
TIP: The configprop:spring.messages.basename[] property supports a list of locations, either a package qualifier or a resource resolved from the classpath root.
|
||||
The configprop:spring.messages.common-messages[] property supports a list of property file resources.
|
||||
|
||||
See javadoc:org.springframework.boot.autoconfigure.context.MessageSourceProperties[] for more supported options.
|
||||
|
|
Loading…
Reference in New Issue