写点什么

Spring 源码学习 13:initMessageSource

发布于: 2021 年 01 月 04 日

前言


在阅读完 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。



相关推荐



发布于: 2021 年 01 月 04 日阅读数: 29
用户头像

个人公众号:『 程序员小航 』 2020.07.30 加入

某不知名互联网公司 Java 程序员一枚。记录工作学习中的技术、开发及源码笔记;分享生活中的见闻感悟。

评论

发布
暂无评论
Spring 源码学习 13:initMessageSource