首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring 源码学习 13:initMessageSource

Spring 源码学习 13:initMessageSource

作者头像
程序员小航
发布2021-01-12 14:28:39
7270
发布2021-01-12 14:28:39
举报
文章被收录于专栏:程序员小航程序员小航

前言

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

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

MessageSource 国际化

如官网1.15.1. Internationalization using MessageSource[1]所示,主要作用就是使用国际化,定制不同的消息。

需要注意的是 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。

引用链接:

[1]

Spring 官方文档: https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#context-functionality-messagesource

- <End /> -

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-01-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序员小航 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • MessageSource 国际化
  • 使用
    • 1. 创建国际化文件
      • 2. 声明 MessageSource
        • 3. 测试结果
        • initMessageSource 源码
        • 总结
        • 引用链接:
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档