在 Spring Boot 中,LocaleContextHolder.getLocale() 用于获取当前线程绑定的 Locale 信息。当使用自定义的 LocaleResolver 时,理解其执行与否的场景,可以帮助我们更好地控制 Locale 的解析过程。以下是一些典型场景,说明自定义的 LocaleResolver 何时执行或不执行:
一、LocaleResolver 执行的情况
-
当请求中有语言设置时 :
Spring 会通过自定义的
LocaleResolver来解析请求中的Locale信息。常见的策略是通过Accept-Language头、URL 参数或 Cookie 来决定应该使用哪个Locale。 -
请求处理器或拦截器触发时 :
在处理 HTTP 请求时,自定义的
LocaleResolver会在HandlerInterceptor或Controller中被调用。例如,使用LocaleChangeInterceptor可以自动处理Locale的变更,并将其应用于自定义的LocaleResolver中。 -
Spring MVC 流程中 :
Spring MVC 框架会在处理请求时调用配置的
LocaleResolver。默认情况下,Spring MVC 会调用自定义的LocaleResolver解析Locale,然后将其绑定到LocaleContextHolder上。
二、LocaleResolver 不执行的情况
-
直接调用
LocaleContextHolder.getLocale()而没有经过请求处理时 :如果直接在业务代码中调用
LocaleContextHolder.getLocale(),而没有经过 HTTP 请求或 Spring MVC 流程,那么LocaleResolver不会被自动触发。在这种情况下,LocaleContextHolder可能会返回一个默认的Locale,而不是基于请求的Locale。 -
多线程场景中未绑定
Locale:如果代码在多线程环境下运行,并且当前线程没有绑定
Locale(比如异步任务中没有显式设置),那么LocaleResolver也不会执行。此时,LocaleContextHolder.getLocale()可能会返回null或默认的Locale。 -
未配置
LocaleResolver时 :如果项目中没有配置任何
LocaleResolver(如AcceptHeaderLocaleResolver、CookieLocaleResolver),Spring 会使用默认的Locale,而不会触发自定义的LocaleResolver。 -
未通过拦截器或未显式设置
Locale时 :如果没有配置
LocaleChangeInterceptor或者通过其他方式主动修改Locale,则自定义的LocaleResolver不会被调用,LocaleContextHolder.getLocale()返回的可能只是应用启动时默认的Locale。
三、如何确保自定义的 LocaleResolver 被执行?
-
配置
LocaleChangeInterceptor:确保在项目中配置了
LocaleChangeInterceptor,并设置相应的参数(例如通过 URL 参数修改语言环境),这样可以触发LocaleResolver。 -
确保通过
LocaleResolver解析Locale:确保请求经过 Spring MVC 的处理流程,这样
LocaleResolver才会被自动调用。你可以在@Controller方法或HandlerInterceptor中依赖于 Spring 的LocaleResolver来获取当前Locale。