zoukankan      html  css  js  c++  java
  • spring学习总结004 --- IOC容器启动源码(MessageSource)

    ApplicationContext的refresh方法的下一个方法为:initMessageSource,用于初始化国际化信息

    spring加载国际化资源文件的接口类MessageSource,spring提供了如下两个类:

    org.springframework.context.support.ReloadableResourceBundleMessageSource

    org.springframework.context.support.ResourceBundleMessageSource

    二者的区别为国际化资源文件路径的差异:

    (1)ReloadableResourceBundleMessageSource能够读取classpath下的资源文件及外部文件

    (2)ResourceBundleMessageSource只能读取classpath下的资源文件

    1、MessageSource接口

    2、ReloadableResourceBundleMessageSource和ResourceBundleMessageSource示例

    @Slf4j
    public class Test1 {
        public static void main(String[] args) {
            ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:bean1.xml");
    
            MessageSource messageSource1 = (MessageSource) context.getBean("messageSource1");
            log.info("Msg1:{}", messageSource1.getMessage("name", new Object[] { "bale" }, Locale.US));
    
            MessageSource messageSource2 = (MessageSource) context.getBean("messageSource2");
            log.info("Msg2:{}", messageSource2.getMessage("name", new Object[] { "bale" }, Locale.US));
        }
    }
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd">
    
        <bean class="org.springframework.context.support.ReloadableResourceBundleMessageSource" id="messageSource1">
            <property name="cacheSeconds" value="5" />
            <property name="basename" value="classpath:/i18n/messages" />
        </bean>
    
        <bean class="org.springframework.context.support.ResourceBundleMessageSource" id="messageSource2">
            <property name="basename" value="i18n/messages" />
            <property name="cacheSeconds" value="5" />
        </bean>
    
    </beans>

    运行结果:

    3、initMessageSource流程

    protected void initMessageSource() {
       //获取Bean工厂,一般是DefaultListBeanFactory
       ConfigurableListableBeanFactory beanFactory = getBeanFactory();
       //首先判断是否已有xml文件定义了id为messageSource的bean对象
       if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
          //如果有,则从Bean工厂得到这个bean对象
          this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
          //当父类context不为空,并且这个bean对象是HierarchicalMessageSource类型
          if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
             //为HierarchicalMessageSource的实现类
             HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
             //设置父类MessageSource,此处设置内部的parent messageSource
             if (hms.getParentMessageSource() == null) {
                hms.setParentMessageSource(getInternalParentMessageSource());
             }
          }
       }
       else {
          //如果没有xml文件定义信息源对象,新建DelegatingMessageSource类作为messageSource的Bean
          //因为DelegatingMessageSource类实现了HierarchicalMessageSource接口,而这个接口继承了MessageSource这个类
          //因此实现了这个接口的类,都是MessageSource的子类,因此DelegatingMessageSource也是一个MessageSource
          DelegatingMessageSource dms = new DelegatingMessageSource();
          //给这个DelegatingMessageSource添加父类消息源
          dms.setParentMessageSource(getInternalParentMessageSource());
          this.messageSource = dms;
          //将这个messageSource实例注册到Bean工厂中
          beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
       }
    }
  • 相关阅读:
    推荐一本SQL经典书籍
    准备升级包包版游戏大厅
    《博客园精华集软件工程分册》第三轮筛选结果
    (翻译)《Expert .NET 2.0 IL Assembler》 第八章 基本类型和签名(一)
    如何输入人名间的顿号
    推荐一个下名人传记电子书的好地方
    asp.net 2.0 中使用web.config存储数据库连接字符串
    Asp.Net小技巧之在client端调用server端事件:
    C#编码好习惯
    把ip转换成对应的城市名
  • 原文地址:https://www.cnblogs.com/sniffs/p/13257406.html
Copyright © 2011-2022 走看看