Check for existence of ResourceBundle before creating MessageSource
Irritatingly a ResourceBundleMessageSource never gives up trying to create a resource bundle for every message resolution, so to stop it logging all those warnings (and probably sucking performance-wise) we need to disable the MessageSource if a bundle is not provided. Fixes gh-1019
This commit is contained in:
parent
1567964e14
commit
0def7644c2
|
@ -16,16 +16,25 @@
|
||||||
|
|
||||||
package org.springframework.boot.autoconfigure;
|
package org.springframework.boot.autoconfigure;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.MissingResourceException;
|
||||||
|
import java.util.ResourceBundle;
|
||||||
|
|
||||||
|
import org.springframework.boot.autoconfigure.MessageSourceAutoConfiguration.ResourceBundleCondition;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionOutcome;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||||
import org.springframework.boot.bind.RelaxedPropertyResolver;
|
import org.springframework.boot.autoconfigure.condition.SpringBootCondition;
|
||||||
import org.springframework.context.EnvironmentAware;
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
import org.springframework.context.MessageSource;
|
import org.springframework.context.MessageSource;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.ConditionContext;
|
||||||
|
import org.springframework.context.annotation.Conditional;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.context.support.ResourceBundleMessageSource;
|
import org.springframework.context.support.ResourceBundleMessageSource;
|
||||||
import org.springframework.core.Ordered;
|
import org.springframework.core.Ordered;
|
||||||
import org.springframework.core.annotation.Order;
|
import org.springframework.core.annotation.Order;
|
||||||
import org.springframework.core.env.Environment;
|
import org.springframework.core.type.AnnotatedTypeMetadata;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
import static org.springframework.util.StringUtils.commaDelimitedListToStringArray;
|
import static org.springframework.util.StringUtils.commaDelimitedListToStringArray;
|
||||||
|
@ -39,28 +48,77 @@ import static org.springframework.util.StringUtils.trimAllWhitespace;
|
||||||
@Configuration
|
@Configuration
|
||||||
@ConditionalOnMissingBean(MessageSource.class)
|
@ConditionalOnMissingBean(MessageSource.class)
|
||||||
@Order(Ordered.HIGHEST_PRECEDENCE)
|
@Order(Ordered.HIGHEST_PRECEDENCE)
|
||||||
public class MessageSourceAutoConfiguration implements EnvironmentAware {
|
@Conditional(ResourceBundleCondition.class)
|
||||||
|
@EnableConfigurationProperties
|
||||||
|
@ConfigurationProperties(prefix = "spring.messages")
|
||||||
|
public class MessageSourceAutoConfiguration {
|
||||||
|
|
||||||
private RelaxedPropertyResolver environment;
|
private String basename = "messages";
|
||||||
|
|
||||||
@Override
|
private String encoding = "utf-8";
|
||||||
public void setEnvironment(Environment environment) {
|
|
||||||
this.environment = new RelaxedPropertyResolver(environment, "spring.messages.");
|
private int cacheSeconds = -1;
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public MessageSource messageSource() {
|
public MessageSource messageSource() {
|
||||||
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
|
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
|
||||||
String basename = this.environment.getProperty("basename", "messages");
|
if (StringUtils.hasText(this.basename)) {
|
||||||
if (StringUtils.hasText(basename)) {
|
|
||||||
messageSource
|
messageSource
|
||||||
.setBasenames(commaDelimitedListToStringArray(trimAllWhitespace(basename)));
|
.setBasenames(commaDelimitedListToStringArray(trimAllWhitespace(this.basename)));
|
||||||
}
|
}
|
||||||
String encoding = this.environment.getProperty("encoding", "utf-8");
|
messageSource.setDefaultEncoding(this.encoding);
|
||||||
messageSource.setDefaultEncoding(encoding);
|
messageSource.setCacheSeconds(this.cacheSeconds);
|
||||||
messageSource.setCacheSeconds(this.environment.getProperty("cacheSeconds",
|
|
||||||
Integer.class, -1));
|
|
||||||
return messageSource;
|
return messageSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getBasename() {
|
||||||
|
return this.basename;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBasename(String basename) {
|
||||||
|
this.basename = basename;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEncoding() {
|
||||||
|
return this.encoding;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEncoding(String encoding) {
|
||||||
|
this.encoding = encoding;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCacheSeconds() {
|
||||||
|
return this.cacheSeconds;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCacheSeconds(int cacheSeconds) {
|
||||||
|
this.cacheSeconds = cacheSeconds;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static class ResourceBundleCondition extends SpringBootCondition {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ConditionOutcome getMatchOutcome(ConditionContext context,
|
||||||
|
AnnotatedTypeMetadata metadata) {
|
||||||
|
String basename = context.getEnvironment().getProperty(
|
||||||
|
"spring.messages.basename", "messages");
|
||||||
|
if (!StringUtils.hasText(basename)) {
|
||||||
|
return ConditionOutcome.noMatch("Empty spring.messages.basename");
|
||||||
|
}
|
||||||
|
for (String name : commaDelimitedListToStringArray(trimAllWhitespace(basename))) {
|
||||||
|
try {
|
||||||
|
ResourceBundle.getBundle(name, Locale.getDefault(),
|
||||||
|
context.getClassLoader());
|
||||||
|
}
|
||||||
|
catch (MissingResourceException e) {
|
||||||
|
return ConditionOutcome
|
||||||
|
.noMatch("Bundle found for spring.messages.basename: " + name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ConditionOutcome.match("Bundle found for spring.messages.basename: "
|
||||||
|
+ basename);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,10 +46,10 @@ public class MessageSourceAutoConfigurationTests {
|
||||||
@Test
|
@Test
|
||||||
public void testMessageSourceCreated() throws Exception {
|
public void testMessageSourceCreated() throws Exception {
|
||||||
this.context = new AnnotationConfigApplicationContext();
|
this.context = new AnnotationConfigApplicationContext();
|
||||||
this.context.register(MessageSourceAutoConfiguration.class,
|
|
||||||
PropertyPlaceholderAutoConfiguration.class);
|
|
||||||
EnvironmentTestUtils.addEnvironment(this.context,
|
EnvironmentTestUtils.addEnvironment(this.context,
|
||||||
"spring.messages.basename:test/messages");
|
"spring.messages.basename:test/messages");
|
||||||
|
this.context.register(MessageSourceAutoConfiguration.class,
|
||||||
|
PropertyPlaceholderAutoConfiguration.class);
|
||||||
this.context.refresh();
|
this.context.refresh();
|
||||||
assertEquals("bar",
|
assertEquals("bar",
|
||||||
this.context.getMessage("foo", null, "Foo message", Locale.UK));
|
this.context.getMessage("foo", null, "Foo message", Locale.UK));
|
||||||
|
@ -58,10 +58,10 @@ public class MessageSourceAutoConfigurationTests {
|
||||||
@Test
|
@Test
|
||||||
public void testMultipleMessageSourceCreated() throws Exception {
|
public void testMultipleMessageSourceCreated() throws Exception {
|
||||||
this.context = new AnnotationConfigApplicationContext();
|
this.context = new AnnotationConfigApplicationContext();
|
||||||
this.context.register(MessageSourceAutoConfiguration.class,
|
|
||||||
PropertyPlaceholderAutoConfiguration.class);
|
|
||||||
EnvironmentTestUtils.addEnvironment(this.context,
|
EnvironmentTestUtils.addEnvironment(this.context,
|
||||||
"spring.messages.basename:test/messages,test/messages2");
|
"spring.messages.basename:test/messages,test/messages2");
|
||||||
|
this.context.register(MessageSourceAutoConfiguration.class,
|
||||||
|
PropertyPlaceholderAutoConfiguration.class);
|
||||||
this.context.refresh();
|
this.context.refresh();
|
||||||
assertEquals("bar",
|
assertEquals("bar",
|
||||||
this.context.getMessage("foo", null, "Foo message", Locale.UK));
|
this.context.getMessage("foo", null, "Foo message", Locale.UK));
|
||||||
|
@ -72,10 +72,10 @@ public class MessageSourceAutoConfigurationTests {
|
||||||
@Test
|
@Test
|
||||||
public void testBadEncoding() throws Exception {
|
public void testBadEncoding() throws Exception {
|
||||||
this.context = new AnnotationConfigApplicationContext();
|
this.context = new AnnotationConfigApplicationContext();
|
||||||
this.context.register(MessageSourceAutoConfiguration.class,
|
|
||||||
PropertyPlaceholderAutoConfiguration.class);
|
|
||||||
EnvironmentTestUtils.addEnvironment(this.context,
|
EnvironmentTestUtils.addEnvironment(this.context,
|
||||||
"spring.messages.encoding:rubbish");
|
"spring.messages.encoding:rubbish");
|
||||||
|
this.context.register(MessageSourceAutoConfiguration.class,
|
||||||
|
PropertyPlaceholderAutoConfiguration.class);
|
||||||
this.context.refresh();
|
this.context.refresh();
|
||||||
// Bad encoding just means the messages are ignored
|
// Bad encoding just means the messages are ignored
|
||||||
assertEquals("blah", this.context.getMessage("foo", null, "blah", Locale.UK));
|
assertEquals("blah", this.context.getMessage("foo", null, "blah", Locale.UK));
|
||||||
|
|
Loading…
Reference in New Issue