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国际化多语言支持教程
SpringBoot源码学习系列之Locale自动配置的更多相关文章
- SpringBoot源码学习系列之异常处理自动配置
SpringBoot源码学习系列之异常处理自动配置 1.源码学习 先给个SpringBoot中的异常例子,假如访问一个错误链接,让其返回404页面 在浏览器访问: 而在其它的客户端软件,比如postm ...
- SpringBoot源码学习系列之SpringMVC自动配置
目录 1.ContentNegotiatingViewResolver 2.静态资源 3.自动注册 Converter, GenericConverter, and Formatter beans. ...
- SpringBoot源码学习系列之嵌入式Servlet容器
目录 1.博客前言简单介绍 2.定制servlet容器 3.变换servlet容器 4.servlet容器启动原理 SpringBoot源码学习系列之嵌入式Servlet容器启动原理 @ 1.博客前言 ...
- SpringBoot源码学习系列之@PropertySource不支持yaml读取原因
然后,为什么@PropertySource注解默认不支持?可以简单跟一下源码 @PropertySource源码: 根据注释,默认使用DefaultPropertySourceFactory类作为资源 ...
- SpringBoot源码学习系列之启动原理简介
本博客通过debug方式简单跟一下Springboot application启动的源码,Springboot的启动源码是比较复杂的,本博客只是简单梳理一下源码,浅析其原理 为了方便跟源码,先找个Ap ...
- 源码学习系列之SpringBoot自动配置(篇一)
源码学习系列之SpringBoot自动配置源码学习(篇一) ok,本博客尝试跟一下Springboot的自动配置源码,做一下笔记记录,自动配置是Springboot的一个很关键的特性,也容易被忽略的属 ...
- 源码学习系列之SpringBoot自动配置(篇二)
源码学习系列之SpringBoot自动配置(篇二)之HttpEncodingAutoConfiguration 源码分析 继上一篇博客源码学习系列之SpringBoot自动配置(篇一)之后,本博客继续 ...
- SpringBoot源码解析系列文章汇总
相信我,你会收藏这篇文章的 本篇文章是这段时间撸出来的SpringBoot源码解析系列文章的汇总,当你使用SpringBoot不仅仅满足于基本使用时.或者出去面试被面试官虐了时.或者说想要深入了解一下 ...
- Java并发包源码学习系列:阻塞队列BlockingQueue及实现原理分析
目录 本篇要点 什么是阻塞队列 阻塞队列提供的方法 阻塞队列的七种实现 TransferQueue和BlockingQueue的区别 1.ArrayBlockingQueue 2.LinkedBloc ...
随机推荐
- wxxcx_learn
32个字符组成的一组随即字符串 function getRandChar($length){ $str = null; $strPol = "ABCDEFGHIJKLMNOPQRSTUVWX ...
- centos7 php(mariadb)安装pdo
环境:centos7+php5.4.16+mariadb5.5.52 在centos7环境下安装PDO,安装的时候都是自己分开安装的,先装的PHP(httpd)后装的mariadb. 数据库安装完成后 ...
- 《Java基础知识》Java类的定义及其实例化
类必须先定义才能使用.类是创建对象的模板,创建对象也叫类的实例化. 下面通过一个简单的例子来理解Java中类的定义: public class Dog { String name; int age; ...
- 创建基于ASP.NET core 3.1 的RazorPagesMovie项目(一)-创建和使用默认的模板
声明:参考于asp.net core 3.1 官网(以后不再说明) 本教程是系列教程中的第一个教程,介绍生成 ASP.NET Core Razor Pages Web 应用的基础知识. 在本系列结束时 ...
- Nginx的配置文件位置以及组成部分结构讲解
场景 Ubuntu Server 16.04 LTS上怎样安装下载安装Nginx并启动: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/detai ...
- Linux7 64安装 oracle 11g Error in invoking target 'agent nmhs' of makefile
在makefile中添加链接libnnz11库的参数修改$ORACLE_HOME/sysman/lib/ins_emagent.mk,将$(MK_EMAGENT_NMECTL)修改为:$(MK_EMA ...
- Python活力练习Day4
Day4:将列表的值按相反顺序依次输出 eg : input : list = [1,2,3,4,5] output : [5,4,3,2,1] 方法一:时间复杂度O(n),其中 n ...
- 1001 害死人不偿命的(3n+1)猜想 (15 分)
卡拉兹(Callatz)猜想: 对任何一个正整数 n,如果它是偶数,那么把它砍掉一半:如果它是奇数,那么把 (3n+1) 砍掉一半.这样一直反复砍下去,最后一定在某一步得到 n=1.卡拉兹在 1950 ...
- Css里的box-shadow的值分别代表什么
以下为例: box-shadow:1px 2px 3px 4px color inset; 1px:表示沿x轴的正方向的长度(如果是负数,则为沿x轴的负方向的长度); 2px:表示沿y轴的正方向的长度 ...
- UWP 利用VisualTreeHelper查找页面中的元素
一般我们在展示数据的时候,都会采用DataTemplate的预先设置数据模板,再使用Set ItemsSource的方式进行数据绑定 这样就能满足大部分的需求. 不过有时候需要对页面已经展示出来的元素 ...