前言
在浏览完 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。
相干举荐
- Spring 源码学习 12:registerBeanPostProcessors
- Spring 源码学习 11:invokeBeanFactoryPostProcessors
- Spring 源码学习 10:prepareBeanFactory 和 postProcessBeanFactory