Spring(十一) 国际化
参考文献
Spring国际化使用场景
- 普通国际化文案
- Bean Validation校验国际化文案
- Web站点页面渲染
- Web MVC错误消息提示
Spring国际化接口
-
核心接口:
org.springframework.context.MessageSource
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19public interface MessageSource {
/**
* 获取国际化信息
* @param code 表示国际化资源中的属性名;
* @param args用于传递格式化串占位符所用的运行期参数;
* @param defaultMessage 当在资源找不到对应属性名时,返回defaultMessage参数所指定的默认信息;
* @param locale 表示本地化对象
*/
String getMessage(String code, ; Object[] args, String defaultMessage, Locale locale)
/**
* 与上面的方法类似,只不过在找不到资源中对应的属性名时,直接抛出NoSuchMessageException 异常
*/
String getMessage(String code, Object[] args, Locale locale)throws NoSuchMessageException;
/**
* @param MessageSourceResolvable 将属性名、参数数组以及默认信息封装起来,它的功能和第一个方法相同
*/
String getMessage(MessageSourceResolvable resolvable, Locale locale) throws NoSuchMessageException;
} -
主要概念
- 文案模板编码(code)
- 文案模板参数(args)
- 区域(Locale)
层次性MessageSource
- Spring 层次性接口回顾
org.springframework.beans.factory.HierarchicalBeanFactory
org.springframework.context.ApplicationContext
org.springframework.beans.factory.config.BeanDefinition
- Spring 层次性国际化接口
org.springframework.context.HierarchicalMessageSource
Java国际化标准实现
-
核心接口
- 抽象实现:
java.util.ResourceBundle
- Properties资源实现:
java.util.PropertyResourceBundle
- 具体实现:
java.util.ListResourceBundle
- 抽象实现:
-
ResourceBundle核心特性
- Key-Value设计
- 层次性设计
- 缓存设计
- 字符编码控制:
java.util.ResourceBundle.Control
(@Since 1.6
) Control SPI
扩展:java.util.spi.ResourceBundleControlProvider
(@Since 1.8
)
Java文本格式化
- 核心接口:
java.text.MessageFormat
- 基本用法:
- 设置消息格式模式:
new MessageFormat(...)
; - 格式化:
format(new Object[]{...})
;
- 设置消息格式模式:
- 消息格式模式:
- 格式元素:
{ArgumentIndex(,FormatType,(FormatStyle))}
FormatType
: 消息格式类型,可选项,每种类型在number,date,time
和choice
类型选其一FormatStyle
: 消息格式风格, 可选项,可包括:short
,medium
,long
,full
,integer
,currency
,percent
- 格式元素:
- 高级特性
- 重置消息格式模式
- 重置
java.util.Locale
- 重置
java.text.Format
MessageSource开箱即用实现
- 基于
ResourceBundle + MessageFormat
组合 MessageSource 实现org.springframework.context.support.ResourceBundleMessageSource
- 可重载
Properties + MessageFormat
组合 MessageSource 实现org.springframework.context.support.ReloadableResourceBundleMessageSource
- 通过编程的方式提供国际化信息
org.springframework.context.support.StaticMessageSource
MessageSource内建依赖
- MessageSource 內建 Bean 可能来源
- 预注册 Bean 名称为:
messageSource
,类型为:MessageSource Bean
- 默认內建实现 -
DelegatingMessageSource
- 层次性查找 MessageSource 对象
- 预注册 Bean 名称为:
Spring中使用国际化的3个步骤
- 通常在
ApplicationContext
类型的容器中使用国际化3个步骤- 创建国际化文件
- 向容器中注册一个
MessageSource
类型的bean
,bean
名称必须为:messageSource
- 调用
AbstractApplicationContext
中的getMessage
来获取国际化信息,其内部将交给第二步中注册的messageSource
名称的bean进行处理
创建国际化文件
-
国际化文件命名格式:
名称_语言_地区.properties
-
message.properties
1
2name=您的姓名
personal_introduction=默认个人介绍:{0},{1} -
message_cn_ZH.properties
1
2name=姓名
personal_introduction=个人介绍:{0},{1},{0} -
message_en_GB.properties
1
2name=Full name
personal_introduction=personal_introduction:{0},{1},{0}
Spring
中注册国际化的bean
1 | import org.springframework.context.annotation.Bean; |
使用
1 | import org.junit.Test; |
动态参数使用
1 |
|
监控国际化文件的变化
1 | import org.springframework.context.MessageSource; |
国际化信息存在db中
1 | import org.springframework.beans.factory.InitializingBean; |
1 | import org.springframework.context.MessageSource; |
bean
名称为什么必须是messageSource
org.springframework.context.support.AbstractApplicationContext#refresh
内部会调用org.springframework.context.support.AbstractApplicationContext#initMessageSource
- 这个方法用来初始化MessageSource,方法内部会查找当前容器中是否有
messageSource
名称的bean
,如果有就将其作为处理国际化的对象,如果没有找到,此时会注册一个名称为messageSource的MessageSource
1 | /** |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 HoleLin's Blog!