diff --git a/spring-context/src/main/java/org/springframework/context/support/AbstractResourceBasedMessageSource.java b/spring-context/src/main/java/org/springframework/context/support/AbstractResourceBasedMessageSource.java
index d9b09d50cf95..ee0eb6cde85a 100644
--- a/spring-context/src/main/java/org/springframework/context/support/AbstractResourceBasedMessageSource.java
+++ b/spring-context/src/main/java/org/springframework/context/support/AbstractResourceBasedMessageSource.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2018 the original author or authors.
+ * Copyright 2002-2019 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.
@@ -17,6 +17,7 @@
package org.springframework.context.support;
import java.util.LinkedHashSet;
+import java.util.Locale;
import java.util.Set;
import org.springframework.lang.Nullable;
@@ -43,6 +44,9 @@ public abstract class AbstractResourceBasedMessageSource extends AbstractMessage
private boolean fallbackToSystemLocale = true;
+ @Nullable
+ private Locale defaultLocale;
+
private long cacheMillis = -1;
@@ -143,6 +147,7 @@ protected String getDefaultEncoding() {
* {@code java.util.ResourceBundle}. However, this is often not desirable
* in an application server environment, where the system Locale is not relevant
* to the application at all: set this flag to "false" in such a scenario.
+ * @see #setDefaultLocale
*/
public void setFallbackToSystemLocale(boolean fallbackToSystemLocale) {
this.fallbackToSystemLocale = fallbackToSystemLocale;
@@ -152,11 +157,46 @@ public void setFallbackToSystemLocale(boolean fallbackToSystemLocale) {
* Return whether to fall back to the system Locale if no files for a specific
* Locale have been found.
* @since 4.3
+ * @deprecated as of 5.2.2, in favor of {@link #getDefaultLocale()}
*/
+ @Deprecated
protected boolean isFallbackToSystemLocale() {
return this.fallbackToSystemLocale;
}
+ /**
+ * Specify a default Locale to fall back to, as an alternative to falling back
+ * to the system Locale.
+ *
Default is to fall back to the system Locale. You may override this with
+ * a locally specified default Locale here, or enforce no fallback locale at all
+ * through disabling {@link #setFallbackToSystemLocale "fallbackToSystemLocale"}.
+ * @since 5.2.2
+ * @see #setFallbackToSystemLocale
+ * @see #getDefaultLocale()
+ */
+ public void setDefaultLocale(@Nullable Locale defaultLocale) {
+ this.defaultLocale = defaultLocale;
+ }
+
+ /**
+ * Determine a default Locale to fall back to: either a locally specified default
+ * Locale or the system Locale, or {@code null} for no fallback locale at all.
+ * @since 5.2.2
+ * @see #setDefaultLocale
+ * @see #setFallbackToSystemLocale
+ * @see Locale#getDefault()
+ */
+ @Nullable
+ protected Locale getDefaultLocale() {
+ if (this.defaultLocale != null) {
+ return this.defaultLocale;
+ }
+ if (this.fallbackToSystemLocale) {
+ return Locale.getDefault();
+ }
+ return null;
+ }
+
/**
* Set the number of seconds to cache loaded properties files.
*
diff --git a/spring-context/src/main/java/org/springframework/context/support/ReloadableResourceBundleMessageSource.java b/spring-context/src/main/java/org/springframework/context/support/ReloadableResourceBundleMessageSource.java
index d65869b14f65..eb8438793b11 100644
--- a/spring-context/src/main/java/org/springframework/context/support/ReloadableResourceBundleMessageSource.java
+++ b/spring-context/src/main/java/org/springframework/context/support/ReloadableResourceBundleMessageSource.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2018 the original author or authors.
+ * Copyright 2002-2019 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.
@@ -237,6 +237,7 @@ protected PropertiesHolder getMergedProperties(Locale locale) {
if (mergedHolder != null) {
return mergedHolder;
}
+
Properties mergedProps = newProperties();
long latestTimestamp = -1;
String[] basenames = StringUtils.toStringArray(getBasenameSet());
@@ -253,6 +254,7 @@ protected PropertiesHolder getMergedProperties(Locale locale) {
}
}
}
+
mergedHolder = new PropertiesHolder(mergedProps, latestTimestamp);
PropertiesHolder existing = this.cachedMergedProperties.putIfAbsent(locale, mergedHolder);
if (existing != null) {
@@ -279,10 +281,15 @@ protected List calculateAllFilenames(String basename, Locale locale) {
return filenames;
}
}
+
+ // Filenames for given Locale
List filenames = new ArrayList<>(7);
filenames.addAll(calculateFilenamesForLocale(basename, locale));
- if (isFallbackToSystemLocale() && !locale.equals(Locale.getDefault())) {
- List fallbackFilenames = calculateFilenamesForLocale(basename, Locale.getDefault());
+
+ // Filenames for default Locale, if any
+ Locale defaultLocale = getDefaultLocale();
+ if (defaultLocale != null && !defaultLocale.equals(locale)) {
+ List fallbackFilenames = calculateFilenamesForLocale(basename, defaultLocale);
for (String fallbackFilename : fallbackFilenames) {
if (!filenames.contains(fallbackFilename)) {
// Entry for fallback locale that isn't already in filenames list.
@@ -290,7 +297,10 @@ protected List calculateAllFilenames(String basename, Locale locale) {
}
}
}
+
+ // Filename for default bundle file
filenames.add(basename);
+
if (localeMap == null) {
localeMap = new ConcurrentHashMap<>();
Map> existing = this.cachedFilenames.putIfAbsent(basename, localeMap);
diff --git a/spring-context/src/main/java/org/springframework/context/support/ResourceBundleMessageSource.java b/spring-context/src/main/java/org/springframework/context/support/ResourceBundleMessageSource.java
index af5a1f071ab1..6df9cdbf9980 100644
--- a/spring-context/src/main/java/org/springframework/context/support/ResourceBundleMessageSource.java
+++ b/spring-context/src/main/java/org/springframework/context/support/ResourceBundleMessageSource.java
@@ -461,7 +461,8 @@ public ResourceBundle newBundle(String baseName, Locale locale, String format, C
@Override
@Nullable
public Locale getFallbackLocale(String baseName, Locale locale) {
- return (isFallbackToSystemLocale() ? super.getFallbackLocale(baseName, locale) : null);
+ Locale defaultLocale = getDefaultLocale();
+ return (defaultLocale != null && !defaultLocale.equals(locale) ? defaultLocale : null);
}
@Override