MessageSource
用于国际化,大家需要先了解一下 java.util.ResourceBundle
,这个是 java
用来处理国际化,标准的公共类,具体使用如下:
public static void main(String args[]) {ResourceBundle bundle = ResourceBundle.getBundle("my", new Locale("zh", "CN"));String cancel = bundle.getString("cancelKey");System.out.println(cancel);bundle = ResourceBundle.getBundle("my", Locale.US);cancel = bundle.getString("cancelKey");System.out.println(cancel);bundle = ResourceBundle.getBundle("my", Locale.getDefault());cancel = bundle.getString("cancelKey");System.out.println(cancel);bundle = ResourceBundle.getBundle("my", Locale.GERMAN);cancel = bundle.getString("cancelKey");System.out.println(cancel);bundle = ResourceBundle.getBundle("my");for (String key : bundle.keySet()) {System.out.println(bundle.getString(key));}}
说明:
ResourceBundle
用于获取对于的 key
的 value
,ResourceBundle
的值怎么来呢?是通过另外一个类,进行创建的 ResourceBundle.Control
,这里分 java.class
和 java.properties
加载方式,就是可以通过 properties
和 class
配置国际化,
// 略 代码...
spring 的 ResourceBundleMessageSource
是用于 propertis
文及加载,继承了 ResourceBundle.Control
并重写 newBundle()
,这样才能加载 MessageSource 配置的 国际化目录 。
// ResourceBundleMessageSource.MessageSourceControl@Override@Nullablepublic ResourceBundle newBundle(String baseName, Locale locale, String format, ClassLoader loader, boolean reload)throws IllegalAccessException, InstantiationException, IOException {// <1> 这里只处理 properties 文件// Special handling of default encodingif (format.equals("java.properties")) {String bundleName = toBundleName(baseName, locale);final String resourceName = toResourceName(bundleName, "properties");final ClassLoader classLoader = loader;final boolean reloadFlag = reload;InputStream inputStream;try {inputStream = AccessController.doPrivileged((PrivilegedExceptionAction<InputStream>) () -> {InputStream is = null;if (reloadFlag) {URL url = classLoader.getResource(resourceName);if (url != null) {URLConnection connection = url.openConnection();if (connection != null) {connection.setUseCaches(false);is = connection.getInputStream();}}}else {is = classLoader.getResourceAsStream(resourceName);}return is;});}catch (PrivilegedActionException ex) {throw (IOException) ex.getException();}if (inputStream != null) {String encoding = getDefaultEncoding();if (encoding != null) {try (InputStreamReader bundleReader = new InputStreamReader(inputStream, encoding)) {return loadBundle(bundleReader);}}else {try (InputStream bundleStream = inputStream) {return loadBundle(bundleStream);}}}else {return null;}}else {// Delegate handling of "java.class" format to standard Controlreturn super.newBundle(baseName, locale, format, loader, reload);}}
说明:
Spring
的 MessageSource
就是采用 java
的 ResourceBundle
进行处理的,国际化可分为两种配置,java.class
和 java.properties
,类图如下:
Spring 里面采用 ResourceBundleMessageSource
来配置 .properties
文件, MessageSource
示例如下:
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><!-- message source --><bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"><!-- <1> 这只国际化目录 --><property name="defaultEncoding" value="UTF-8" /><property name="basename" value="messageSource.lan" /><property name="useCodeAsDefaultMessage" value="true" /><!-- <2> --><!-- lan 文件分为 --><!-- lan.properties --><!-- lan_en_US.properties --><!-- lan_zh_CN.properties --></bean></beans>
public static void main(String[] args) {ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("messageSource/message-source.xml");System.err.println(context.getMessage("appName", null, Locale.getDefault()));System.err.println(context.getMessage("appName", null, Locale.CANADA));System.err.println(context.getMessage("appName", null, Locale.US));}
说明:
ps:完结~