Spring學習系列(四)——Spring中的國際化


1.Java中的國際化
國際化(Internationalization)簡稱 i18n,簡單來說就是不同國家/地區/語言的用戶,訪問同一個程序,得到對應的本地化資源。

首先要確定國家/地區/語言(Locale類)

然后根據不同的Locale獲取對應的本地化資源(locale敏感的)。

而本地化資源相關的主要有兩種:ResourceBundle和Format抽象類的子類。
①Jdk為ResourceBundle抽象類提供了兩個子類(ListResourceBundle和PropertyResourceBundle)

當然也可以參考ResourceBundle編寫自定義的子類MyResources和XMLResourceBundle等(源碼注釋部分)。

(FORMAT_DEFAULT默認使用java.class和java.properties兩種格式)其中properties的命名規則basename_language_country.properties。

 

②Format,相對簡單不再過多描述。

Format子類中關於Local的使用。

2.Spring中的國際化

首先說明Spring中國際化的支持是AbstractApplicationContext中定義的默認bean(ApplicationContext實現了MessageSource接口),  private MessageSource messageSource;

而在基於Spring的Web應用中使用我們更多關注的是如何確定Local的問題,而對資源的獲取則更多的是基於配置。
①通過LocaleResolver獲取Local

  • 讀取客戶端瀏覽器的默認語言,根據Request Headers中的Accept-language來判斷。
  • 客戶端傳參,並基於Session和Cookie的對Local進行管理(例如一些網站的語言切換選項)。

使用RequestContextUtils.getLocale(request)獲取Local;

參考DispatcherServlet的initLocaleResolver()方法,在bean中配置不同的LocaleResolver實現

②通過MessageSource獲取ResoureBundle

  • 對與一些簡單的資源,我們可以采用properties中配置
  • 在Web應用中,如果資源文件過多,使用properties維護將是個麻煩,可以采用數據庫存儲結合緩存技術實現。

③messageResoure的配置

核心是AbstractApplicationContext中initMessageSource()中涉及的HierarchicalMessageSource接口;

 

由AbstractBeanFactory中的containsLocalBean(String name)區分為兩類:使用配置的HierarchicalMessageSource實現和DelegatingMessageSource(HierarchicalMessageSource的簡單實現)

而在messageSource配置class時,有兩個常用的HierarchicalMessageSource實現可供選擇:ResourceBundleMessageSource和ReloadableResourceBundleMessageSource

兩者都是利用資源名通過getMessage()接口就可以加載整套的國際化資源文件,唯一區別在於ReloadableResourceBundleMessageSource可以定時刷新資源文件,以便在應用程序不重啟的情況下感知資源文件的變化。很多生產系統都需要長時間持續運行,系統重啟會給運行帶來很大的負面影響,這時通過該實現類就可以解決國際化信息更新的問題。上面的配置中cacheSeconds屬性讓ReloadableResourceBundleMessageSource每5秒鍾刷新一次資源文件(在真實的應用中,刷新周期不能太短,否則頻繁的刷新將帶來性能上的負面影響,一般不建議小於30分鍾)。cacheSeconds默認值為-1表示永不刷新,此時,該實現類的功能就蛻化為ResourceBundleMessageSource的功能。

 ④簡單的代碼示例

a.在spring配置文件中定義messageSource<bean>

b.定義不同Local的properties文件,命名規則basename_language_country.properties和java中的一致。

c.代碼

  ApplicationContext applicationContext=new FileSystemXmlApplicationContext("classpath:spring-config.xml");
      String message=applicationContext.getMessage("HelloWorld",new Object[]{"hello",new Date()}, Locale.CHINA);

小結:可以看出使用spring的國際化更加靈活(ReloadableResourceBundleMessageSource的動態讀取),基於MessageFormat的參數化列表,以及中文支持可以設置編碼格式(java中處理相對麻煩)。

 3.總結

Java中:重點了解ResoureBundle的使用參考源碼解析圖。

Spring中:重點分兩部分,①通過LocaleResolver獲取Local,②通過通過MessageSource獲取ResoureBundle

Spring的國際化是基於Java(Jdk)國際化的擴展,在Web項目中使用更加靈活。

閱讀Java(其實這里使用Jdk更合適)源碼還能夠捋清思路,Spring源碼閱讀着有些吃力,目前階段只能結合一些博客挑重點部分的源碼進行解讀了。

4.參考資料

spring學習4-國際化

利用Spring進行項目國際化(多語言)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM