SpringBoot源碼學習系列之Locale自動配置


@


MessageSourceAutoConfiguration是國際化語言i18n的自動配置類

MessageSourceAutoConfiguration.ResourceBundleCondition 源碼:

protected static class ResourceBundleCondition extends SpringBootCondition {
		//定義一個map緩存池
		private static ConcurrentReferenceHashMap<String, ConditionOutcome> cache = new ConcurrentReferenceHashMap<>();

		@Override
		public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) {
			String basename = context.getEnvironment().getProperty("spring.messages.basename", "messages");
			ConditionOutcome outcome = cache.get(basename);//緩存拿得到,直接從緩存池讀取
			if (outcome == null) {//緩存拿不到,重新讀取
				outcome = getMatchOutcomeForBasename(context, basename);
				cache.put(basename, outcome);
			}
			return outcome;
		}

		private ConditionOutcome getMatchOutcomeForBasename(ConditionContext context, String basename) {
			ConditionMessage.Builder message = ConditionMessage.forCondition("ResourceBundle");
			for (String name : StringUtils.commaDelimitedListToStringArray(StringUtils.trimAllWhitespace(basename))) {
				for (Resource resource : getResources(context.getClassLoader(), name)) {
					if (resource.exists()) {
					//匹配resource bundle資源
						return ConditionOutcome.match(message.found("bundle").items(resource));
					}
				}
			}
			return ConditionOutcome.noMatch(message.didNotFind("bundle with basename " + basename).atAll());
		}
		//解析資源文件
		private Resource[] getResources(ClassLoader classLoader, String name) {
			String target = name.replace('.', '/');//spring.messages.basename參數值的點號換成斜桿
			try {
				return new PathMatchingResourcePatternResolver(classLoader)
						.getResources("classpath*:" + target + ".properties");
			}
			catch (Exception ex) {
				return NO_RESOURCES;
			}
		}

	}

ok,這個自動配置類還是比較容易理解的,所以本博客列舉一些注意要點

1、spring.messages.cache-duration

  • spring.messages.cache-duration在2.2.1版本,指定的是s為單位,找到SpringBoot的MessageSourceAutoConfiguration自動配置類
    在這里插入圖片描述

2、LocaleResolver 的方法名必須為localeResolver

  • 如下代碼,LocaleResolver 的方法名必須為localeResolver,否則會報錯
@Bean
    public LocaleResolver localeResolver(){
        CustomLocalResolver localResolver = new CustomLocalResolver();
        localResolver.setDefaultLocale(webMvcProperties.getLocale());
        return localResolver;
    }

原理:
跟一下源碼,點進LocaleChangeInterceptor類
在這里插入圖片描述

在這里插入圖片描述
DispatcherServlet是Spring一個很重要的分發器類,在DispatcherServlet的一個init方法里找到這個LocaleResolver的init方法
在這里插入圖片描述
這個IOC獲取的bean類名固定為localeResolver,寫例子的時候,我就因為改了bean類名,導致一直報錯,跟了源碼才知道Bean類名要固定為localeResolver
在這里插入圖片描述

3、默認LocaleResolver

繼續跟源碼,拋異常的時候,也是會獲取默認的LocaleResolver的
在這里插入圖片描述

在這里插入圖片描述

在這里插入圖片描述
找到一個properties配置文件,全局搜索
在這里插入圖片描述
找到資源文件,確認,還是默認為AcceptHeaderLocaleResolver
在這里插入圖片描述

4、指定默認的locale

  • WebMvcAutoConfiguration的自動配置
    配置了locale屬性的時候,還是選用AcceptHeaderLocaleResolver作為默認的LocaleResolver
spring.mvc.locale=zh_CN

WebMvcAutoConfiguration.localeResolver方法源碼,ConditionalOnMissingBean主鍵的意思是LocaleResolver沒有自定義的時候,才作用,ConditionalOnProperty的意思,有配了屬性才走這里的邏輯
在這里插入圖片描述

5、localeChangeInterceptor指定傳參

  • 攔截器攔截的請求參數默認為locale,要使用其它參數,必須通過攔截器設置 ,eg:localeChangeInterceptor.setParamName("lang");
    在這里插入圖片描述

附錄:

  • Locale解析器種類
    LocalResolver種類有:CookieLocaleResolver(Cookie)、SessionLocaleResolver(會話)、FixedLocaleResolver、AcceptHeaderLocaleResolver(默認)、.etc

具體實現,參考我的博客:SpringBoot系列之i18n國際化多語言支持教程


免責聲明!

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



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