Message sources

Auto-detecting message sources

If a module has a message source packaged in the right location it will be auto-detected and configured. The following default message properties will be configured automatically if they are present on the classpath:

  • /messages/MODULE_RESOURCES/ (deprecated)

  • /messages/MODULE_RESOURCES/

  • /messages/MODULE_RESOURCES/default/*.properties

The default message sources are configured using an instance of AcrossModuleMessageSource. AcrossModuleMessageSource is a special case of Spring’s ReloadableResourceBundleMessageSource. If development mode is active and the development locations for the module have been configured, the classpath lookups are replaced by physical file lookups with a cache time of 1 second. This is very useful during development where updates to resource bundles can be instantly visible.

Automatic configuration of message sources only happens if the module does not define a bean named messageSource. The following section details how you can manually define message sources.

Message source hierarchy

Across has its own custom behavior in relation to messageSource beans declared in modules. Each module can declare a default MessageSource bean named messageSource. Upon bootstrap this message source will be added to a hierarchy along with all other messageSource beans. Once bootstrap is complete, a message will be looked up in all sources defined.

Default message source hierarchy

By default Across uses the following approach to build a message source hierarchy:

  • a messageSource bean from a parent ApplicationContext is considered to be application specific and should allow customizing the messages of the modules

  • a messageSource bean in a module is expected to be able to customize messages from other modules that the current module depends on

    • this is also interpreted as: the message source of a module takes precedence over the message source of earlier modules

As a result, once a context is fully bootstrapped and a message is requested, the sources are queried in the following order:

  1. message sources of the parent ApplicationContext (and up its hierarchy if more than one parent)

  2. message sources of the modules in reverse bootstrap order (last bootstrapped first)

Once an AcrossContext is fully bootstrapped, messages will be looked up in the hierarchy built from all bootstrapped modules. During the bootstrap phase however, only message sources from earlier modules and the parent ApplicationContext are available.
Reverting to default spring behavior

Default Spring behavior with message sources is that a MessageSource in an ApplicationContext will get the MessageSource of the parent ApplicationContext as its parent. In a module setup, this would mean that a message would first be looked up in the source of the module, and only afterwards in the source of the context. You can force the default behavior to apply by annotating a messageSource bean with @Internal. Note that in that case the messageSource will remain internal to the module where it’s declared.

Configuring a custom message source for a module with development mode support
public class ModuleConfig
	public MessageSource messageSource() {
        AcrossModuleMessageSource source = new AcrossModuleMessageSource();
        source.setBasenames( "classpath:/my/module/messages" );

        return source;