前言

在浏览完 registerBeanPostProcessors 源码之后, 下一步就进入到 initMessageSource,这一步次要作用是初始化国际化文件。

仍然如之前所示,先通过官网理解到国际化的用法,而后再对源码进行钻研。

MessageSource 国际化

如官网1.15.1. Internationalization using MessageSource所示,次要作用就是应用国际化,定制不同的音讯。

须要留神的是 MessageSource 定义的 Bean 名字必须为 messageSource, 而如果找不到则会默认注册 DelegatingMessageSource 作为 messageSource 的 Bean。

应用

1. 创立国际化文件

2. 申明 MessageSource

在 JavaConfig 中 申明 MessageSource , 记得名字肯定要叫做 messageSource

@Configuration@ComponentScan("com.liuzhihang")public class JavaConfig {    @Bean(name = "messageSource")    public MessageSource getMessageSource() {        ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();        messageSource.setDefaultEncoding("UTF-8");        messageSource.addBasenames("message", "message_en");        return messageSource;    }}

3. 测试后果

public class AnnotationConfigApplicationTest {    public static void main(String[] args) {        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();        context.register(JavaConfig.class);        context.refresh();        MessageSource messageSource = context.getBean(MessageSource.class);        String zhMessage = messageSource.getMessage("user.name", null, null, Locale.CHINA);        String enMessage = messageSource.getMessage("user.name", null, null, Locale.ENGLISH);        System.out.println("zhMessage = " + zhMessage);        System.out.println("enMessage = " + enMessage);    }}

如上所示,执行之后输入后果如下:

晓得了国际化是如何应用的之后,再想一想这一步源码,就晓得是什么作用了吧!

initMessageSource 源码

protected void initMessageSource() {    ConfigurableListableBeanFactory beanFactory = getBeanFactory();    // Bean 的名称必须要是 messageSource    if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {        this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);        // Make MessageSource aware of parent MessageSource.        if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {            HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;            if (hms.getParentMessageSource() == null) {                // Only set parent context as parent MessageSource if no parent MessageSource                // registered already.                hms.setParentMessageSource(getInternalParentMessageSource());            }        }        if (logger.isTraceEnabled()) {            logger.trace("Using MessageSource [" + this.messageSource + "]");        }    }    else {        // Use empty MessageSource to be able to accept getMessage calls.        // 否则则应用默认的        DelegatingMessageSource dms = new DelegatingMessageSource();        dms.setParentMessageSource(getInternalParentMessageSource());        this.messageSource = dms;        beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);        if (logger.isTraceEnabled()) {            logger.trace("No '" + MESSAGE_SOURCE_BEAN_NAME + "' bean, using [" + this.messageSource + "]");        }    }}

这块源码惟一值得关注的中央就是,Bean 的名称必须要是 messageSource 。

总结

本文通过官网,理解到什么是国际化,以及国际化的应用,并联合代码和源码,知其然,知其所以然。

当然本文须要留神的中央就是国际化 MessageSource 的 Bean 名称要必须为 messageSource。

相干举荐

  • Spring 源码学习 12:registerBeanPostProcessors
  • Spring 源码学习 11:invokeBeanFactoryPostProcessors
  • Spring 源码学习 10:prepareBeanFactory 和 postProcessBeanFactory