• Spring 源码学习 13:initMessageSource


    前言

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

    相关推荐

  • 相关阅读:
    jquery层级选择器学习笔记
    html 大于号 小于号 空格显示
    MySql存储过程二---变量
    MySql 存储过程一--基本语法及参数介绍
    MySql delimiter
    MySql 关联查询
    MySql 数据库导入导出
    markdown 换行
    WPF 之 MVVM
    对memtester源码分析
  • 原文地址:https://www.cnblogs.com/liuzhihang/p/source-spring-13.html
Copyright © 2020-2023  润新知