自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Spring國際化的應(yīng)用及原理詳解

開發(fā) 前端
Spring 還提供了一個ReloadableResourceBundleMessageSource 類。該變體支持相同的捆綁文件格式,但比基于 JDK 的標準 ResourceBundleMessageSource 實現(xiàn)更靈活。

環(huán)境:Spring5.3.23

1. 簡介

Spring國際化(Spring Internationalization,簡稱i18n)是Spring框架提供的一種機制,用于支持多語言的應(yīng)用程序。它使得開發(fā)者能夠輕松地在應(yīng)用程序中實現(xiàn)不同語言的支持,從而滿足全球化的需求。通過Spring國際化,開發(fā)者可以將應(yīng)用程序的文本、標簽、消息等資源抽取出來,并使用合適的語言文件進行翻譯,使得應(yīng)用程序能夠根據(jù)用戶的語言偏好自動切換語言。這種機制不僅簡化了多語言支持的實現(xiàn),還使得應(yīng)用程序更加易于維護和擴展。在Spring國際化的實現(xiàn)中,主要涉及到了MessageSource、LocaleResolver等核心組件,它們共同協(xié)作,實現(xiàn)了語言切換的功能。通過使用Spring國際化的API,開發(fā)者可以方便地定義語言區(qū)域、加載資源文件、處理消息等操作,從而快速構(gòu)建多語言的應(yīng)用程序。

2. API介紹

ApplicationContext 接口擴展了一個名為 MessageSource 的接口,因此提供了國際化("i18n")功能。Spring 還提供了 HierarchicalMessageSource 接口,該接口可以分層解析消息。這些接口共同構(gòu)成了 Spring 實現(xiàn)消息解析的基礎(chǔ)。這些接口定義的方法包括:

  • String getMessage(String code, Object[] args, String default, Locale loc)

用于從 MessageSource 獲取消息的基本方法。如果在指定的本地沒有找到消息,則使用默認消息。通過標準庫提供的 MessageFormat 功能,傳入的任何參數(shù)都會成為替換值。

  • String getMessage(String code, Object[] args, Locale loc)

與前一種方法基本相同,但有一點不同:不能指定默認信息。如果找不到信息,就會拋出 NoSuchMessageException 異常。

  • String getMessage(MessageSourceResolvable resolvable, Locale locale)

前面方法中使用的所有屬性也都封裝在一個名為 MessageSourceResolvable 的類中,你可以使用該方法。

3. 國際化初始化

Spring容器ApplicationContext初始化過程中,會從容器中查找MessageSource類型的Bean。并且該Bean的名稱必須是 messageSource。如果找到了這樣一個 Bean,對前面方法的所有調(diào)用都會委托給消息源。如果沒有找到消息源,ApplicationContext 會嘗試查找包含同名Bean的父類。如果找到了,它就會使用該 bean 作為消息源。如果 ApplicationContext 無法找到任何消息源,則會實例化一個空的 DelegatingMessageSource,以便能夠接受對上述方法的調(diào)用。

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);
    }
  }
}

4. 國際化配置

基于Spring環(huán)境

@Bean(AbstractApplicationContext.MESSAGE_SOURCE_BEAN_NAME)
public MessageSource messageSource() {
  ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource() ;
  // 這里設(shè)置的是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。文件內(nèi)容如下:

message_zh_CN.properties

#姓名必須填寫
user.name.empty=\u59D3\u540D\u5FC5\u987B\u586B\u5199

message_en_US.properties

user.name.empty=name is required

調(diào)用

try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class)) {
  // Locale.CHINA或者Locale.US
  System.out.println(context.getMessage("user.name.empty", null, Locale.CHINA)) ;
}

基于SpringBoot環(huán)境

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中初始化的。

在接口調(diào)用時,我們只需要指定Access-Language header

圖片圖片

5. 其它配置

Spring為我們提供了一個便捷的類,可以更方便的訪問消息源,項目中只需要注冊如下bean:

@Bean
public MessageSourceAccessor messageSourceAccessor(MessageSource messageSource) {
  MessageSourceAccessor accessor = new MessageSourceAccessor(messageSource) ;
  return accessor ;
}

訪問

@Resource
private 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 實現(xiàn)更靈活。特別是,它允許從任何 Spring 資源位置(而不僅僅是從類路徑)讀取文件,并支持捆綁屬性文件的熱重載(同時在兩者之間有效地緩存它們)。

責(zé)任編輯:武曉燕 來源: Spring全家桶實戰(zhàn)案例源碼
相關(guān)推薦

2011-08-29 09:48:30

springMVC

2010-01-04 13:09:51

Silverlight

2022-07-27 10:39:14

Spring代碼IDEA

2011-08-11 13:26:30

iPhoneNSLocalized

2011-08-18 15:24:40

iPhone國際化

2011-05-17 09:39:38

JavaSE

2011-07-08 11:13:42

Cocoa Touch XCode

2010-03-02 16:44:59

CentOS Mono

2010-07-28 14:52:29

Flex國際化

2024-05-17 08:25:06

數(shù)據(jù)驅(qū)動React語言包

2024-01-17 10:16:22

前端國際化消息鍵

2023-01-31 10:29:26

JavaScript國際化國際化庫

2011-08-19 13:13:14

struts2Java

2009-06-25 16:04:30

2009-06-03 08:30:30

禚佳春法航華為

2009-01-19 09:06:31

gettextPHP國際化編程

2017-01-09 16:24:07

滴滴Android 端 App

2009-12-29 15:05:29

WPF支持國際化

2009-02-04 15:04:13

2024-09-04 10:27:53

點贊
收藏

51CTO技術(shù)棧公眾號