From 3dc5e7b1d5fb166e66b0eb718aa57d246e967de9 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Wed, 13 Nov 2019 23:41:26 +0100 Subject: [PATCH] Avoid String concatenation for lookup in StaticMessageSource Closes gh-22451 --- .../context/support/StaticMessageSource.java | 72 ++++++++++++++----- .../support/StaticMessageSourceTests.java | 1 - 2 files changed, 54 insertions(+), 19 deletions(-) diff --git a/spring-context/src/main/java/org/springframework/context/support/StaticMessageSource.java b/spring-context/src/main/java/org/springframework/context/support/StaticMessageSource.java index 26df79d7b7..9f8ace3ab2 100644 --- a/spring-context/src/main/java/org/springframework/context/support/StaticMessageSource.java +++ b/spring-context/src/main/java/org/springframework/context/support/StaticMessageSource.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. @@ -36,33 +36,35 @@ import org.springframework.util.Assert; */ public class StaticMessageSource extends AbstractMessageSource { - /** Map from 'code + locale' keys to message Strings. */ - private final Map messages = new HashMap<>(); - - private final Map cachedMessageFormats = new HashMap<>(); + private final Map> messageMap = new HashMap<>(); @Override + @Nullable protected String resolveCodeWithoutArguments(String code, Locale locale) { - return this.messages.get(code + '_' + locale.toString()); + Map localeMap = this.messageMap.get(code); + if (localeMap == null) { + return null; + } + MessageHolder holder = localeMap.get(locale); + if (holder == null) { + return null; + } + return holder.getMessage(); } @Override @Nullable protected MessageFormat resolveCode(String code, Locale locale) { - String key = code + '_' + locale.toString(); - String msg = this.messages.get(key); - if (msg == null) { + Map localeMap = this.messageMap.get(code); + if (localeMap == null) { return null; } - synchronized (this.cachedMessageFormats) { - MessageFormat messageFormat = this.cachedMessageFormats.get(key); - if (messageFormat == null) { - messageFormat = createMessageFormat(msg, locale); - this.cachedMessageFormats.put(key, messageFormat); - } - return messageFormat; + MessageHolder holder = localeMap.get(locale); + if (holder == null) { + return null; } + return holder.getMessageFormat(); } /** @@ -75,7 +77,7 @@ public class StaticMessageSource extends AbstractMessageSource { Assert.notNull(code, "Code must not be null"); Assert.notNull(locale, "Locale 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()) { logger.debug("Added message [" + msg + "] for code [" + code + "] and Locale [" + locale + "]"); } @@ -95,7 +97,41 @@ public class StaticMessageSource extends AbstractMessageSource { @Override 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; + } } } diff --git a/spring-context/src/test/java/org/springframework/context/support/StaticMessageSourceTests.java b/spring-context/src/test/java/org/springframework/context/support/StaticMessageSourceTests.java index 5c0a5e1223..ca5b1bf675 100644 --- a/spring-context/src/test/java/org/springframework/context/support/StaticMessageSourceTests.java +++ b/spring-context/src/test/java/org/springframework/context/support/StaticMessageSourceTests.java @@ -59,7 +59,6 @@ public class StaticMessageSourceTests extends AbstractApplicationContextTests { @Test @Override public void count() { - // These are only checked for current Ctx (not parent ctx) assertCount(15); } -- GitLab