Spring - Multiple MessageSources
This article shows how to configure multiple message sources in a Spring Boot application for different environments.
Configuring MessageSource
Beans
The problem is that we want to actually define two Spring beans of type org.springframework.context.MessageSource
: one for the local development environment and the other one for all the other environments supported. During development, we want to use Spring’s org.springframework.context.support.ReloadableResourceBundleMessageSource
to have automatic reloading of the message source. In the other environments though, we want to use Spring’s static ResourceBundleMessageSource
. Both beans should be named messageSource
as this is the conventional name for the MessageSource
. Also Spring Boot predefines a bean with such a name and type.
As we want to have two MessageSource
beans with the same name, we decided to use two @Configuration
classes, one for each environment, each one define a messageSource
bean. We already have a configuration called WebConfiguration
which is executed only in a web-environment, that is the place to add the new bean definitions:
@Configuration
@ConditionalOnWebApplication
public class WebConfiguration {
// ... other @Bean configurations for the web application
@Configuration
@Profile("development")
public class LocalMessageSourceConfiguration {
@Bean
public ReloadableResourceBundleMessageSource messageSource() {
ReloadableResourceBundleMessageSource source = new ReloadableResourceBundleMessageSource();
source.setBasename("classpath:messages");
source.setCacheSeconds(0);
source.setDefaultEncoding("UTF-8");
return source;
}
}
@Configuration
@Profile("!development")
public class MessageSourceConfiguration {
@Bean
public ResourceBundleMessageSource messageSource() {
ResourceBundleMessageSource source = new ResourceBundleMessageSource();
source.setBasename("messages");
source.setDefaultEncoding("UTF-8");
return source;
}
}
}
The trick we use here to add two @Configuration
annotated inner classes which both define the bean named messageSource
of some MessageSource
interface implementation.
In addition, we use the @Profile("development")
annotation for the configuration that should be active in the development environment. For the other configuration, we use the NOT operator in the profile name given to @Profile
to have this configuration only being executed in all environments except development
: @Profile("!development")
.
The default encoding for java.util.ResourceBundle
is ISO-8859-1, therefore this is the default encoding Spring’s MessageSource
implementations assume. Starting with Java 9, the default encoding of ResourceBundle
will be UTF-8 so we chose to use UTF-8 right from the start.
Notice that source.setCacheSeconds(0);
in the case of the ReloadableResourceBundleMessageSource
configures the message source to reload the message source based on the modification date of the message source file(s). This check is done with every message source access, so it is strongly discouraged to use such a configured MessageSource
in production.
Summary
In this article we showed how to configure different types of MessageSource
beans for different environments in Spring Boot.