ResourceBundle
Java 提供了ResourceBundle类,可以实现特定区域(语言环境)的资源加载。以便我们在编码时可以使用一个ResourceBundle而不用考虑特定的语言环境信息,程序自动通过当前的用户的语言环境信息来加载特定资源。
ResourceBundle的使用比较简单,如下面的代码。
public class ResourceBundleDemo {
public static void main(String[] args) throws UnsupportedEncodingException {
ResourceBundle rb = ResourceBundle.getBundle("test");
System.out.println(rb.getString("key1"));
rb = ResourceBundle.getBundle("test", Locale.GERMAN);
System.out.println(rb.getString("key1"));
}
}
ResourceBundle通过了getBundle 工厂方法创建的实例默认被缓存。如果ResourceBundle被缓存多次调用getBundle 方法返回同一个实例。getBundle 的客户端可以清除缓存、管理缓存的缓存时间。参考:clearCache方法、ResourceBundle.Control.getTimeToLive和ResourceBundle.Control.needsReload。
Java平台提供了ResourceBundle两个子类ListResourceBundle 和PropertyResourceBundle。
ResourceBundle工厂方法在加载资源的过程中需要ResourceBundle.Control提供必须要的信息。ResourceBundle.Control 提供包括:bundle名字、创建Bundle、资源寻找等信息。默认的ResourceBundle.Control 可以被覆盖。默认的ResourceBundle.Control实现了两种格式资源的加载,class 格式和properties 格式。例如下面的代码:
ResourceBundle rb = ResourceBundle.getBundle(“MyResource”);
那么会加载MyResource.class(及相关语言区域后缀的class),如果class找不到,会加载MyResource.properties(及相关语言区域后缀的properties)的相关文件(通过PropertyResourceBundle)。
MessageFomat
MessageFormat 提供了以与语言无关方式生成连接消息的方式。使用此方法构造向终端用户显示的消息。MessageFormat 本身不实现特定于语言环境的行为。特定于语言环境的行为是由所提供的模式和用于已插入参数的子格式来定义的。
MessageFormat 简单实例如下代码:
int planet = 7;
String event = "a disturbance in the Force";
String result = MessageFormat.format(
"At {1,time} on {1,date}, there was {2} on planet {0,number,integer}.",
planet, new Date(), event);
MessageFormat具体使用以及pattern模式可以参考javadoc。
MessageFormat可以和ResourceBundle配合做到个不同语言环境的用户显示。
public static void main(String[] args) {
Date d = new Date();
MessageFormat format = new MessageFormat("今天是{0,date ,yyyy-MM-dd}");
System.out.println(format.format(new Object[]{d}));
format.applyPattern("today is {0,date, dd/MM/yy}");
System.out.println(format.format(new Object[]{d}));
}
Spring MessageSource
Spring MessageSource接口,用来支持参数化和国际化消息。
public interface MessageSource {
@Nullable
String getMessage(String code, @Nullable Object[] args, @Nullable String defaultMessage, Locale locale);
String getMessage(String code, @Nullable Object[] args, Locale locale) throws NoSuchMessageException;
String getMessage(MessageSourceResolvable resolvable, Locale locale) throws NoSuchMessageException;
}
Spring 提供了两个开箱即用的MessageSource实现,ResourceBundleMessageSource 和ReloadableResourceBundleMessageSource。
在AbstractApplicationContext中的initMessageSource方法,检测有无配置名称为MESSAGE_SOURCE_BEAN_NAME(messageSource)的bean,如果没有配置则生成一个DelegatingMessageSource 进行注册。initMessageSource的源码如下:
/**
* Initialize the MessageSource.
* Use parent's if none defined in this context.
*/
protected void initMessageSource() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
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 + "]");
}
}
}
DelegatingMessageSource仅仅代理AbstractApplicationContext父类中的messageSource实例,或者父AbstractApplicationContext(因为AbstractApplicationContext实现了MessageSource的接口)。
AbstractApplicationContext也实现了MessageSource的接口,相关的实现都是通过委托内部的messageSource进行处理的。源码如下:
@Override
public String getMessage(String code, @Nullable Object[] args, @Nullable String defaultMessage, Locale locale) {
return getMessageSource().getMessage(code, args, defaultMessage, locale);
}
@Override
public String getMessage(String code, @Nullable Object[] args, Locale locale) throws NoSuchMessageException {
return getMessageSource().getMessage(code, args, locale);
}
@Override
public String getMessage(MessageSourceResolvable resolvable, Locale locale) throws NoSuchMessageException {
return getMessageSource().getMessage(resolvable, locale);
}
private MessageSource getMessageSource() throws IllegalStateException {
if (this.messageSource == null) {
throw new IllegalStateException("MessageSource not initialized - " +
"call 'refresh' before accessing messages via the context: " + this);
}
return this.messageSource;
}
项目中,我们如果想使用国际化的内容,需要配置一个名字为“messageResource”的MessageResouce实例,可以使用spring开箱即用的现有实现(ResourceBundle 和 MessageFormat的合集)。
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
相关推荐: 7DGroup性能&测试开发文章持续更新(2019/12/23)
组织 织 简 介 1、7DGroup 简介 性能 能 闲 谈 1、浅谈window桌面GUI技术及图像渲染性能测试实践 2、杂谈:性能测试的范围到底有多大? 3、戏说CPU使用率-驳《CPU使用率度量指标是扯淡!》译文标题 4、对性能测试评估分析优化市场的反思…