Spring通过MessageSource接口提供了国际化(“i18n”)功能。搞明白MessageResource相关接口和类,基本就掌握了国际化功能。
MessageSource接口
定义了消息访问接口。
String getMessage(String code,Object[]args,String default,Locale loc):核心方法,用于从MessageSource检索消息的基本方法(参数说明:code-消息代码;args-消息用到替换值,从{0}对应第一个参数,以此类推;default-消息找不到代替的默认消息;loc-国际化编码)。如果找不到指定区域设置的消息,则使用默认消息。使用标准库提供的MessageFormat功能,传入的任何参数都将成为替换值。
String getMessage(String code,Object[]args,Locale loc):本质上与前面的方法相同,但有一个区别:不能指定默认消息。如果找不到消息,则会引发NoSuchMessageException。
String getMessage(MessageSourceResolvable resolvable,Locale Locale):前面方法中使用的所有属性也封装在一个名为MessageSourceResolvable的类中,您可以将该类与此方法一起使用。
类关系
从图上看,虽然国际化功能比较简单,但Spring的设计和实现还是有点复杂。从使用来说我们只需关注ResourceBundleMessageSource和ReloadableResourceBundleMessage。后者可以看做是前者的增强版,具体区别如下:
1、ResourceBundleMessageSource只是从类路径加载资源文件,ReloadableResourceBundleMessage可从任何资源位置读取文件。
2、ResourceBundleMessageSource限于读取.properties文件,ReloadableResourceBundleMessage还可以读取xml属性文件。
3、ResourceBundleMessageSource不支持配置默认编码(自身默认为““ISO-8859-1””),ReloadableResourceBundleMessage支持。
4、ResourceBundleMessageSource不支持对bundle属性文件的热重新加载,ReloadableResourceBundleMessage支持。
使用
配置
定义消息bean。
<!-- bean名称必须是 messageSource -->
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="defaultEncoding" value ="UTF-8" />
<!-- 消息文件名 -->
<property name="basenames" >
<list>
<!-- 消息文件名,后缀通常是.properties; i18n国际化的文件名格式:文件名_语言编码 为对应语言的配置文件-->
<value>i18n_info</value>
<value>i18n_error</value>
</list>
</property>
</bean>
注:
1、因为Spring的MessageSource基于Java的ResourceBundle,所以它不会合并具有相同基本名称的bundle,而是只使用找到的第一个bundle。具有相同基本名称的后续消息束将被忽略。
2、国际化地区语言码对照表(i18n)https://blog.csdn.net/fujianxinghuo/article/details/126504621
3、对应上面配置的消息文件示例:
框架加载
ApplicationContext容器刷新时,会自动搜索上下文中定义的MessageSource bean。bean的名称必须为messageSource。如果找到这样的bean,则对前面方法的所有调用都将委托给消息源。如果找不到消息源,ApplicationContext将尝试查找包含同名bean的父级,如果存在则作为MessageSource。如果ApplicationContext找不到任何消息源,则会实例化一个空的DelegatingMessageSource,以便能够接受对上面定义的方法的调用。
应用使用
1、用@Autowired注入到bean属性
@Component
public class DemoMessageSource extends BaseDemo{
@Autowired
MessageSource ms;
public void demo() {
super.demo();
// 使用英语
System.out.println("from message_info:"+ms.getMessage("demo.title", null, null,Locale.ENGLISH));
System.out.println("from message_error:"+ms.getMessage("error.except", null, null,Locale.ENGLISH));
// 使用中文
System.out.println("from message_info:"+ms.getMessage("demo.title", null, null,Locale.CHINESE));
System.out.println("from message_error:"+ms.getMessage("error.except", null, null,Locale.CHINESE));
}
}
2、xml模式配置,示例如下:
<bean id="example" class="com.demo.Example">
<property name="messages" ref="messageSource"/>
</bean>
3、还可以使用MessageSourceAware接口获取应用程序容器的MessageSource引用。