title: Database-driven resource bundle in Spring
body: <p>I have problem to make "database-driven resource bundle" work. In example below <code>TextDAO</code> is properly injected during application start, but when <code>messageSource</code> is accessed, a new <code>Messages</code> object is created - that's the point. How to make this work ?</p>
  
  <pre><code>&lt;!-- message source --&gt;
  &lt;bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource"&gt;
      &lt;property name="basename" value="someapp.bundle.Messages" /&gt;
  &lt;/bean&gt;
  </code></pre>
  
  <p><em>Messages.java</em></p>
  
  <pre><code>@Component
  public class Messages extends ListResourceBundle {
  
      @Autowired
      private TextDAO textDAO;
  
      public Messages() {
          log.debug("CONSTRUCTOR");
      }
  
      @Override
      protected Object[][] getContents() {
          // loading messages from DB
          List&lt;Text&gt; texts = textDAO.findAll();  // textDAO is null
          ...
      }
  }
  </code></pre>
  
  <hr>
  
  <h2>RE-OPEN</h2>
  
  <p>As <code>Bozho</code> suggest i did my resource bundle as below, but have problem to dynamically reload it. I suppose that ReloadableResourceBundleMessageSource is for properties files, but maybe it is possible to work this, too.</p>
  
  <pre><code>public class DatabaseDrivenMessageSource extends ReloadableResourceBundleMessageSource {
  
      private Logger log = LoggerFactory.getLogger(getClass());
  
      private final Map&lt;String, Map&lt;String, String&gt;&gt; properties = new HashMap&lt;String, Map&lt;String, String&gt;&gt;();
  
      private TextDAO textDAO;
  
      @Autowired
      public DatabaseDrivenMessageSource(TextDAO textDAO) {
          this.textDAO = textDAO;
          reload();
      }
  
      @Override
      protected MessageFormat resolveCode(String code, Locale locale) {
          String msg = getText(code, locale);
          MessageFormat result = createMessageFormat(msg, locale);
          return result;
      }
  
      @Override
      protected String resolveCodeWithoutArguments(String code, Locale locale) {
          return getText(code, locale);
      }
  
      private String getText(String code, Locale locale) {
          Map&lt;String, String&gt; localized = properties.get(code);
          String textForCurrentLanguage = null;
          if (localized != null) {
              textForCurrentLanguage = localized.get(locale.getLanguage());
              if (textForCurrentLanguage == null) {
                  textForCurrentLanguage = localized.get(Locale.ENGLISH.getLanguage());
              }
          }
          return textForCurrentLanguage != null ? textForCurrentLanguage : code;
      }
  
      public void reload() {
          properties.clear();
          properties.putAll(loadTexts());
      }
  
      protected Map&lt;String, Map&lt;String, String&gt;&gt; loadTexts() {
          log.debug("loadTexts");
          Map&lt;String, Map&lt;String, String&gt;&gt; m = new HashMap&lt;String, Map&lt;String, String&gt;&gt;();
          List&lt;Text&gt; texts = textDAO.findAll();
          for(Text text: texts) {
              Map&lt;String, String&gt; v = new HashMap&lt;String, String&gt;();
              v.put("en", text.getEn());
              v.put("de", text.getDe());
              m.put(text.getKey(), v);
          }
          return m;
      }
  }
  </code></pre>