環境:Spring5.3.23
Spring國際化(Spring Internationalization,簡稱i18n)是Spring框架提供的一種機制,用于支持多語言的應用程序。它使得開發者能夠輕松地在應用程序中實現不同語言的支持,從而滿足全球化的需求。通過Spring國際化,開發者可以將應用程序的文本、標簽、消息等資源抽取出來,并使用合適的語言文件進行翻譯,使得應用程序能夠根據用戶的語言偏好自動切換語言。這種機制不僅簡化了多語言支持的實現,還使得應用程序更加易于維護和擴展。在Spring國際化的實現中,主要涉及到了MessageSource、LocaleResolver等核心組件,它們共同協作,實現了語言切換的功能。通過使用Spring國際化的API,開發者可以方便地定義語言區域、加載資源文件、處理消息等操作,從而快速構建多語言的應用程序。
ApplicationContext 接口擴展了一個名為 MessageSource 的接口,因此提供了國際化("i18n")功能。Spring 還提供了 HierarchicalMessageSource 接口,該接口可以分層解析消息。這些接口共同構成了 Spring 實現消息解析的基礎。這些接口定義的方法包括:
用于從 MessageSource 獲取消息的基本方法。如果在指定的本地沒有找到消息,則使用默認消息。通過標準庫提供的 MessageFormat 功能,傳入的任何參數都會成為替換值。
與前一種方法基本相同,但有一點不同:不能指定默認信息。如果找不到信息,就會拋出 NoSuchMessageException 異常。
前面方法中使用的所有屬性也都封裝在一個名為 MessageSourceResolvable 的類中,你可以使用該方法。
Spring容器ApplicationContext初始化過程中,會從容器中查找MessageSource類型的Bean。并且該Bean的名稱必須是 messageSource。如果找到了這樣一個 Bean,對前面方法的所有調用都會委托給消息源。如果沒有找到消息源,ApplicationContext 會嘗試查找包含同名Bean的父類。如果找到了,它就會使用該 bean 作為消息源。如果 ApplicationContext 無法找到任何消息源,則會實例化一個空的 DelegatingMessageSource,以便能夠接受對上述方法的調用。
public abstract class AbstractApplicationContext { public void refresh() { // 初始化消息源 initMessageSource(); } protected void initMessageSource() { ConfigurableListableBeanFactory beanFactory = getBeanFactory(); // 判斷容器中是否有messageSource if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) { this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class); if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) { HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource; if (hms.getParentMessageSource() == null) { hms.setParentMessageSource(getInternalParentMessageSource()); } } } 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); } }}
@Bean(AbstractApplicationContext.MESSAGE_SOURCE_BEAN_NAME)public MessageSource messageSource() { ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource() ; // 這里設置的是basename,message是文件的前綴(不是包) messageSource.addBasenames("classpath:com/pack/main/databinder/message") ; return messageSource ;}
在包com/pack/main/databinder下建2個文件分別:message_zh_CN.properties和message_en_US.properties。文件內容如下:
message_zh_CN.properties
#姓名必須填寫user.name.empty=/u59D3/u540D/u5FC5/u987B/u586B/u5199
message_en_US.properties
user.name.empty=name is required
調用
try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class)) { // Locale.CHINA或者Locale.US System.out.println(context.getMessage("user.name.empty", null, Locale.CHINA)) ;}
基于SpringBoot環境
spring: messages: basename: message
注意:你需要提供一個默認的message.properties文件
@RestController@RequestMapping("/i18n")public class I18NController { @Resource private ApplicationContext context ; @GetMapping("/index") public String index() { return context.getMessage("user.name.empty", null, "默認消息", LocaleContextHolder.getLocale()) ; } }
Locale從當前線程上下文中獲取。該Locale是在DispatcherServlet中初始化的。
在接口調用時,我們只需要指定Access-Language header
圖片
Spring為我們提供了一個便捷的類,可以更方便的訪問消息源,項目中只需要注冊如下bean:
@Beanpublic MessageSourceAccessor messageSourceAccessor(MessageSource messageSource) { MessageSourceAccessor accessor = new MessageSourceAccessor(messageSource) ; return accessor ;}
訪問
@Resourceprivate MessageSourceAccessor accessor ;@GetMapping("/index")public String index() { return accessor.getMessage("user.name.empty") ;}
在消息文件中定義如下:
#年齡的取值范圍從{0}~{1}user.age.range=/u5E74/u9F84/u7684/u53D6/u503C/u8303/u56F4/u4ECE{0}~{1}
訪問
@GetMapping("/index")public String index() { return accessor.getMessage("user.age.range", new Object[] {1, 100}) ;}
注:Spring 還提供了一個ReloadableResourceBundleMessageSource 類。該變體支持相同的捆綁文件格式,但比基于 JDK 的標準 ResourceBundleMessageSource 實現更靈活。特別是,它允許從任何 Spring 資源位置(而不僅僅是從類路徑)讀取文件,并支持捆綁屬性文件的熱重載(同時在兩者之間有效地緩存它們)。
本文鏈接:http://www.www897cc.com/showinfo-26-57390-0.htmlSpring國際化的應用及原理詳解
聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com