我寫了一個簡單的程式來處理Spring框架的國際化功能,如下所示:
我寫了一個簡單的程式來處理Spring框架的國際化功能。
@SpringBootApplication
public class Application {
@Bean
public LocaleResolver localeResolver(){
SessionLocaleResolver localeResolver = new SessionLocaleResolver() 。
localeResolver.setDefaultLocale(Locale.US)。
return localeResolver。
}
@Bean[/span
public MessageSource resourceBundleMessageSource(){
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource() 。
messageSource.setUseCodeAsDefaultMessage(true)。
messageSource.setBasenames("message")。
return messageSource。
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args)。
}
}
和我的控制器:
@RestController
public class MyController {
@Autowired
@Qualifier(value = " resourceBundleMessageSource")
private MessageSource messageSource;
@GetMapping(path = "/get")
public String getLocale(
@RequestHeader(value = "Accept-Language", required = false) Locale locale) {
return messageSource.getMessage("message.to.user",null, locale);
}
}
我還在src/main/resources檔案夾中創建了message.properties、message_en.properties和message_es.properties。
我的問題是,即使我有一個MessageSource的實體在我的應用程式背景關系中,我必須使用Qualifier(value = "resourceBundleMessageSource"),以便從我的控制器獲得回應,否則,我得到這樣的錯誤。
No message found under code 'message.to.user' for locale 'es'.現在我想知道為什么@Autowired沒有按照預期作業? 即按型別自動連接Bean,在此我有一個MessageSource
uj5u.com熱心網友回復:
--已編輯--
可能是它在自動連接另一個訊息源,這就是為什么當你@自動連接它,并使用它時(它沒有拋出一個例外,而是告訴你它找不到要翻譯的訊息)
你可以通過重命名你的bean宣告來解決這個問題,例如:
@Bean
public MessageSource messageSource(){
然后再呼叫它
private MessageSource messageSource。
對于回退匹配,Bean的名字被認為是一個默認的限定詞 值。因此,你可以用一個id為main的bean來定義,而不是用 嵌套的限定符元素,導致同樣的匹配結果。 然而,盡管你可以使用這個約定來參考特定的 Bean的名稱,但@Autowired從根本上說是關于型別驅動的注入 可選的語意限定詞。這意味著限定符的值。 即使有Bean名稱的回退,也總是有縮小語意的 在型別匹配的集合中。它們在語意上并不表達一個 對唯一bean id的參考。好的限定詞值是main或EMEA 或持久性,表達了一個特定組件的特征,這些特征與Bean ID無關。 獨立于Bean ID的特性,Bean ID可能是在匿名Bean定義的情況下自動生成的。 在匿名Bean定義的情況下,它可能會被自動生成,比如前面的例子中的
正如前面所討論的,限定符也適用于型別化的集合,例如 例如,對 Set。在這種情況下,所有匹配的 bean。 根據已宣告的限定符,所有匹配的 Bean 被注入為一個集合。 這意味著限定詞不一定是唯一的。相反,它們 構成過濾標準。例如,你可以定義多個 MovieCatalog Bean,其限定符的值為 "action",所有的 都被注入到一個被注解為 @Qualifier("action").
。
因此,我相信你有不止一種型別的(MessageSource),這就是為什么當你使用Qualifier時它可以作業,但沒有Qualifier就不行。
uj5u.com熱心網友回復:
你的問題遺漏了一個重要的部分,那就是你正在使用Spring Boot(盡管可以從你有一個@SpringBootApplication注釋主類的事實中推斷出來,但它并不在標簽中)。
Spring Boot已經配置了一個MessageSource,并以messageSource的名義進行配置(這也是Spring中用來確定要使用的主MessageSource的神奇名字)。
您正在添加一個額外的MessageSource,名為resourceBundleMessageSource。
這樣一來,你就有了2個型別為MessageSource的bean。現在Spring會做什么,因為它無法確定使用哪一個,它將使用欄位的名稱(在你的例子中是messageSource)并找到一個具有確切名稱的欄位(在這種情況下是默認的)。
事實上,它是按照設計和檔案的要求作業的,但是你沒有意識到已經有一個MessageSource的預配置。
我也建議使用默認的,并洗掉你自己的MessageSource定義。而是在配置中添加以下內容
spring.messages.use-code-as-default-message=true。
為了實作你在你的自定義控制器中配置的行為。
在你的控制器中,你也不需要獲得Accept-Language,因為那是SessionLocaleResolver所做的,盡管你需要洗掉defaultLocale,這樣才能發揮作用。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/308778.html
標籤:
