提交 3dc5e7b1 编写于 作者: J Juergen Hoeller

Avoid String concatenation for lookup in StaticMessageSource

Closes gh-22451
上级 6fa9871a
/* /*
* 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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
...@@ -36,33 +36,35 @@ import org.springframework.util.Assert; ...@@ -36,33 +36,35 @@ import org.springframework.util.Assert;
*/ */
public class StaticMessageSource extends AbstractMessageSource { public class StaticMessageSource extends AbstractMessageSource {
/** Map from 'code + locale' keys to message Strings. */ private final Map<String, Map<Locale, MessageHolder>> messageMap = new HashMap<>();
private final Map<String, String> messages = new HashMap<>();
private final Map<String, MessageFormat> cachedMessageFormats = new HashMap<>();
@Override @Override
@Nullable
protected String resolveCodeWithoutArguments(String code, Locale locale) { protected String resolveCodeWithoutArguments(String code, Locale locale) {
return this.messages.get(code + '_' + locale.toString()); Map<Locale, MessageHolder> localeMap = this.messageMap.get(code);
if (localeMap == null) {
return null;
}
MessageHolder holder = localeMap.get(locale);
if (holder == null) {
return null;
}
return holder.getMessage();
} }
@Override @Override
@Nullable @Nullable
protected MessageFormat resolveCode(String code, Locale locale) { protected MessageFormat resolveCode(String code, Locale locale) {
String key = code + '_' + locale.toString(); Map<Locale, MessageHolder> localeMap = this.messageMap.get(code);
String msg = this.messages.get(key); if (localeMap == null) {
if (msg == null) {
return null; return null;
} }
synchronized (this.cachedMessageFormats) { MessageHolder holder = localeMap.get(locale);
MessageFormat messageFormat = this.cachedMessageFormats.get(key); if (holder == null) {
if (messageFormat == null) { return null;
messageFormat = createMessageFormat(msg, locale);
this.cachedMessageFormats.put(key, messageFormat);
}
return messageFormat;
} }
return holder.getMessageFormat();
} }
/** /**
...@@ -75,7 +77,7 @@ public class StaticMessageSource extends AbstractMessageSource { ...@@ -75,7 +77,7 @@ public class StaticMessageSource extends AbstractMessageSource {
Assert.notNull(code, "Code must not be null"); Assert.notNull(code, "Code must not be null");
Assert.notNull(locale, "Locale must not be null"); Assert.notNull(locale, "Locale must not be null");
Assert.notNull(msg, "Message must not be null"); Assert.notNull(msg, "Message must not be null");
this.messages.put(code + '_' + locale.toString(), msg); this.messageMap.computeIfAbsent(code, key -> new HashMap<>(4)).put(locale, new MessageHolder(msg, locale));
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
logger.debug("Added message [" + msg + "] for code [" + code + "] and Locale [" + locale + "]"); logger.debug("Added message [" + msg + "] for code [" + code + "] and Locale [" + locale + "]");
} }
...@@ -95,7 +97,41 @@ public class StaticMessageSource extends AbstractMessageSource { ...@@ -95,7 +97,41 @@ public class StaticMessageSource extends AbstractMessageSource {
@Override @Override
public String toString() { public String toString() {
return getClass().getName() + ": " + this.messages; return getClass().getName() + ": " + this.messageMap;
}
private class MessageHolder {
private final String message;
private final Locale locale;
@Nullable
private volatile MessageFormat cachedFormat;
public MessageHolder(String message, Locale locale) {
this.message = message;
this.locale = locale;
}
public String getMessage() {
return this.message;
}
public MessageFormat getMessageFormat() {
MessageFormat messageFormat = this.cachedFormat;
if (messageFormat == null) {
messageFormat = createMessageFormat(this.message, this.locale);
this.cachedFormat = messageFormat;
}
return messageFormat;
}
@Override
public String toString() {
return this.message;
}
} }
} }
...@@ -59,7 +59,6 @@ public class StaticMessageSourceTests extends AbstractApplicationContextTests { ...@@ -59,7 +59,6 @@ public class StaticMessageSourceTests extends AbstractApplicationContextTests {
@Test @Test
@Override @Override
public void count() { public void count() {
// These are only checked for current Ctx (not parent ctx)
assertCount(15); assertCount(15);
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册