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);
}
}