将 Spring 自带的 org.springframework.context.support.ResourceBundleMessageSource 类注册到 bean.xml 中,这个类的作用是获取资源文件的内容,注册到 IoC 的 bean.xml 文件中是为了自动获得此类的对象( Spring 做了一些简化编程的处理)。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="Chinese" class="cn.com.chengang.spring.Chinese"/>
<bean id="American" class="cn.com.chengang.spring.American"/>
<bean id="messageSource " class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames">
<list>
<value>cn.com.chengang.spring.messages</value>
</list>
</property>
</bean>
</beans>
代码说明:
l id="messageSource " 的设置是不变的、必须的。
l ResourceBundleMessageSource 是 Spring 的一个 Message 类。这里还有一个选择,用 ReloadableResourceBundleMessageSource 类,此类可以提供不用重启即可重新加载资源文件的特性(前者对资源文件只加载一次)。对于那种有热修改资源文件的需求,后者比较合适,只是后者在效率上有可能有损耗,因为至少要多一些检查资源文件是否改变的代码(这只是我的猜测,我没有仔佃去读这段的源码)。
l “ basenames ”是不变的、必须的。它是 ResourceBundleMessageSource 的一个属性,在源代码中的定义是“ private String[] basenames; ”,可见它是一个字符串数组。
l “ cn.com.chengang.spring.messages ”是把资源文件的位置传入到 basenames 属性中。注意:三个资源文件只需要将共同的主名(红色字体)传入: messages .properties 、 messages _zh_CN.properties 、 messages _zh_TW.properties 。
3 、使用。修改 MessageTest 类,如下
package cn.com.chengang.spring;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
public class MessageTest {
public static void main(String[] args) {
ApplicationContext ctx = new FileSystemXmlApplicationContext("bean.xml");
String str = ctx.getMessage("chengang", null, null);
System.out.println(str);
}
}
代码说明:
( 1 ) main 方法里
l 第一句取得 bean.xml 文件的配置信息。
l 第二句从资源文件里得到键值 chengang 对应的字符串。
l 第三句将字符串打印出来,结果是打印的是“陈刚”,说明读取的是 messages_zh_CN.properties 资源文件。
( 2 ) ctx.getMessage("chengang", null, null); 有三个参数:
l 第一个是资源文件的键值;
l 第二个是资源文件字符串的参数,由于本字符串没有参数,所以用一个 null (后面给出了一个用到字符串参数的实例);
l 第三个是一个 java.util. Locale 类型的参数。参数为 null ,则表示根据使用者的语言环境来选择 Locale ,因为我用的是中文版的 windows ,所以在取字符串时它自动选择了 messages_zh_CN.properties 资源文件。
这其中还有一个控制点在 JVM , JVM 会根据当前操作系统的语言环境进行相应处理,我们可以通过在 JVM 启动参数中追加“ -Duser.language=zh_TW ”来设定当前 JVM 语言类型,通过 JVM 级的设定,也可以实现自动切换所使用的资源文件类型。
所以这里面的控制语言的方式有三种:从最低层的操作系统的 Locale 设定,到更上一层的 JVM 的 Locale 设定,再到程序一级的 Locale 设定。
package cn.com.chengang.spring;
import java.util.Locale;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
import org.springframework.context.support.ResourceBundleMessageSource;
public class MessageTest {
public static void main(String[] args) {
ApplicationContext ctx = new FileSystemXmlApplicationContext("bean.xml");
String str = ctx.getMessage("chengang", null, null);
System.out.println(str); // 输出“陈刚”
/*
* 使用了 messages.properties
*/
str = ctx.getMessage("chengang", null, new Locale(""));
System.out.println(str);// 输出“ Giles ”
/*
* 使用了 messages_zh_CN.properties
*/
str = ctx.getMessage("chengang", null, new Locale("zh", "CN"));
System.out.println(str);// 输出“陈刚”
/*
* 使用了 messages_zh_TW.properties
*/
str = ctx.getMessage("chengang", null, new Locale("zh", "TW"));
System.out.println(str);// 输出“陳剛”
/*
* 使用了 messages_zh_TW.properties ,从这里可见资源文件的起名可以很随意,
* 比如我们建立一个 messages_123.properties ,在传参数时候就可以这样:
* new Locale("123") ,一样也可以取出 messages_123.properties 中的值
*/
str = ctx.getMessage("chengang", null, new Locale("zh_TW"));
System.out.println(str);// 输出“陳剛”
/*
* 当找不到相应的资源文件时,使用了 messages_zh_CN.properties
*/
str = ctx.getMessage("chengang", null, new Locale("abcd"));
System.out.println(str);// 输出“陈刚”
/**
* 不通过 IoC 注册,直接使用 ResourceBundleMessageSource 类的写法。
*/
ResourceBundleMessageSource s = new ResourceBundleMessageSource();
s.setBasename("cn.com.chengang.spring.messages");
str = s.getMessage("chengang", null, null);
System.out.println(str);// 输出“陈刚”
}
}
代码说明:
前面说过控制语言的方式有三种:从最低层的操作系统的 Locale 设定,到更上一层的 JVM 的 Locale 设定,再到程序一级的 Locale 设定。我认为最佳的方法是在程序一级进行控制:定义一个统一的 Locale 静态变量,然后整个系统中只使用这一个变量,以后就可以通过界面操作设置此 Locale 变量的值,让用户来选择他所需的软件语言。而且我们也可以将此静态变量设成 null 值,来自动选择资源文件。
另外, Locale 里也定义了一些常量,我们可以直接使用而不必去 new 一个 Locale 对象,如:“ Locale.ENGLISH ”。