title: Load i18n message from specific bundle/messageSource using spring:message
body: <p>Coming from Apache Struts, I'm looking for a way to specify from which bundle to get a message while using the spring:message tag like so:</p>
  
  <p><strong>WebConfig.java (messageSources definition)</strong></p>
  
  <pre><code>@Bean
  public ResourceBundleMessageSource messageSource() {
  
      ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
  
      String[] baseNames = {
              "resources.messages.layout.LayoutResources",
              "resources.messages.layout.MenuResources",
              "resources.messages.option.AppConfigResources",
              "resources.messages.global.GlobalResources",
              "resources.messages.contact.ContactResources",
              "resources.messages.currentsession.CurrentSessionResources",
              "resources.messages.welcome.WelcomeResources",
              "resources.messages.user.UserResources",
              "resources.messages.role.RoleResources",
              "resources.messages.profile.ProfileResources"
      };
  
      messageSource.setUseCodeAsDefaultMessage(true);
      messageSource.setDefaultEncoding(StandardCharsets.UTF_8.name());
      messageSource.setBasenames(baseNames);
  
      return messageSource;
  }
  </code></pre>
  
  <p><strong>What I am used to in Struts</strong></p>
  
  <pre><code>&lt;bean:message bundle="userResources" key="label.firstName" /&gt;
  </code></pre>
  
  <p><strong>What I use right now in Spring</strong></p>
  
  <pre><code>&lt;spring:message code="label.firstName" /&gt;
  </code></pre>
  
  <p>That works, but if for any reason in a huge application, the key gets duplicated, Spring will silently choose the first one from the basenames definition.</p>
  
  <p><strong>To reproduce what I had in Struts, I did the following:</strong></p>
  
  <p><strong>Custom JSP tag</strong></p>
  
  <pre><code>&lt;!DOCTYPE html&gt;
  &lt;%@ tag pageEncoding="UTF-8" %&gt;
  
  &lt;%@ attribute name="bundle" required="false" type="java.lang.String" rtexprvalue="false" %&gt;
  &lt;%@ attribute name="key" required="true" type="java.lang.String" rtexprvalue="true" %&gt;
  &lt;%@ attribute name="locale" required="false" type="java.lang.String" rtexprvalue="false" %&gt;
  
  &lt;%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %&gt;  
  &lt;%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %&gt;
  
  &lt;c:choose&gt;
      &lt;c:when test="${empty bundle}"&gt;
          &lt;c:set var="bundleToUse" value="resources.messages.global.GlobalResources" /&gt;
      &lt;/c:when&gt;
  
      &lt;c:otherwise&gt;
          &lt;c:set var="bundleToUse" value="resources.messages.${bundle}" /&gt;
      &lt;/c:otherwise&gt;
  &lt;/c:choose&gt;
  
  &lt;c:choose&gt;
      &lt;c:when test="${empty locale}"&gt;
          &lt;c:set var="localeToUse" value="${pageContext.request.locale.language}" /&gt;
      &lt;/c:when&gt;
  
      &lt;c:otherwise&gt;
          &lt;c:set var="localeToUse" value="${locale}" /&gt;
      &lt;/c:otherwise&gt;
  &lt;/c:choose&gt;
  
  &lt;fmt:setBundle var="bundleObjectToUse" basename="${bundleToUse}" /&gt;
  &lt;fmt:setLocale value="${localeToUse}" /&gt;
  &lt;fmt:message key="${key}" bundle="${bundleObjectToUse}" /&gt;
  </code></pre>
  
  <p><strong>Typical usage</strong></p>
  
  <p><strong>With specific bundle and locale</strong></p>
  
  <pre><code>&lt;t:message bundle="user.UserResources" key="error.userSearch.required" locale="fr"&gt;
  </code></pre>
  
  <p><strong>With specific bundle and default locale</strong></p>
  
  <pre><code>&lt;t:message bundle="option.AppConfigResources" key="label.smtpServerHostname.note"&gt;
  </code></pre>
  
  <p><strong>With key only, falls back to GlobalResources</strong></p>
  
  <pre><code>&lt;t:message key="filterSearch"&gt;
  </code></pre>
  
  <p>I would really like to build something closer to Spring.</p>
  
  <p>Thank you</p>