What is Spring's MessageSource, and how do you use getMessage to resolve a localized message with arguments?
answer
- code + args + Locale
- {0} = MessageFormat placeholder
- bean must be named messageSource
- 3 overloads: default / throws / Resolvable
- messages_fr.properties fallback chain
basics
~20 sMessageSource is Spring's interface for resolving text by a code for a given Locale. You call getMessage(code, args, locale); args fill placeholders like {0} in the properties file, so one code renders in different languages.
solid answer
~30 sMessageSource is Spring's abstraction for internationalized (i18n) text lookup. You resolve a message by a String code, passing an Object[] of arguments and a java.util.Locale; Spring finds the matching properties file (e.g. messages_fr.properties) and substitutes arguments into MessageFormat placeholders {0}, {1}. Three overloads exist: one taking a defaultMessage (returned on a miss), one that throws NoSuchMessageException on a miss, and one taking a MessageSourceResolvable. The ApplicationContext itself implements MessageSource, delegating to a bean that must be named exactly 'messageSource'. In Spring Boot a ResourceBundleMessageSource over the 'messages' basename is auto-configured, so you add messages.properties files per locale and inject MessageSource.
code
java · 22 lines@Configuration
public class I18nConfig {
@Bean
public MessageSource messageSource() {
var ms = new ResourceBundleMessageSource();
ms.setBasename("messages"); // messages.properties, messages_fr.properties...
ms.setDefaultEncoding("UTF-8");
return ms;
}
}
@Service
public class Greeter {
private final MessageSource messages;
public Greeter(MessageSource messages) { this.messages = messages; }
public String greet(String name, Locale locale) {
// messages.properties: greeting=Hello, {0}!
// messages_fr.properties: greeting=Bonjour, {0} !
return messages.getMessage("greeting", new Object[]{name}, locale);
}
}go deeper
Knows getMessage(code, args, locale) and per-locale properties files.
Understands the three overloads, the fallback chain, and the messageSource bean-name requirement.
Explains MessageFormat quoting, default-message vs exception semantics, and Boot auto-configuration.
Frames i18n as an externalization/ops concern; standardizes codes, encoding, and missing-key policy across services.
**What it is.** `org.springframework.context.MessageSource` is Spring's core interface for *internationalization* (i18n) — resolving human-readable text by a symbolic **code** instead of hard-coding strings, so one application can render French, German, etc. based on a **Locale** (`java.util.Locale`). **The three getMessage overloads:** - `getMessage(String code, Object[] args, String defaultMessage, Locale locale)` — returns `defaultMessage` (may be `null`) if the code is not found; never throws. - `getMessage(String code, Object[] args, Locale locale)` — throws `NoSuchMessageException` if the code is missing. - `getMessage(MessageSourceResolvable resolvable, Locale locale)` — resolves an object that carries its own codes/args/default (used by validation errors). **How lookup works.** Messages live in `.properties` files keyed by a **basename** plus a locale suffix: `messages.properties` (default), `messages_fr.properties`, `messages_fr_FR.properties`. For `Locale.FRANCE` Spring tries the most specific file first (`_fr_FR`), then `_fr`, then the base file. Each file holds `code=text` pairs, e.g. `greeting=Hello, {0}!`. **Arguments and placeholders.** When you pass a non-empty `args` array, Spring runs the text through `java.text.MessageFormat`. `{0}` is replaced by `args[0]`, `{1}` by `args[1]`, and typed formats like `{0,number,currency}` or `{0,date,long}` are supported. Gotcha: with args present, a literal single quote must be **doubled** (`''`) because `MessageFormat` treats `'` as an escape. **Wiring.** The `ApplicationContext` *is* a `MessageSource` — but it only works if you register a bean literally named **`messageSource`**; `AbstractApplicationContext` looks that bean up by name during refresh. In Spring Boot, `MessageSourceAutoConfiguration` creates a `ResourceBundleMessageSource` from the `messages` basename automatically (configurable via `spring.messages.*`). You then inject either the `MessageSource` bean or the `ApplicationContext`. **When to use.** Any user-facing text that must vary by language or that you want centralized/externalized: validation messages, emails, UI labels, error responses.
- What happens if the code isn't found?The overload with a defaultMessage returns that default (or null); the overload without one throws NoSuchMessageException. You can also set useCodeAsDefaultMessage=true to return the code itself instead of throwing.
- Why must the bean be named 'messageSource'?AbstractApplicationContext.initMessageSource() looks up a bean by that exact name to back the context's own MessageSource; a differently-named bean is ignored and a DelegatingMessageSource with no parent is used, so lookups fail.
saying these in an interview costs you the question
- Thinking getMessage always throws when a code is missing (the defaultMessage overload doesn't)
- Naming the bean anything other than 'messageSource' and expecting it to work
- Forgetting that placeholders use MessageFormat {0} indexing, not named tokens