可以通过两种不同的方式来获取LocaleResolver实例是技术上的:


通过RequestContextRequestContextUtils.getLocaleResolver(request)
通过注入:@Autowired LocaleResolver localeResolver


但是哪个更好呢?



背景/背景:

我已经实现了自定义的变体语言环境更改拦截器。这是一个HandlerInterceptor,其工作方式与普通的LocaleChangeInterceptor相似,并且它使用注入方式来获取LocaleResolver。有效。

但是今天,我对LocaleChangeInterceptor进行了仔细的研究。我注意到它们没有注入LocaleResolver,而是从请求上下文(RequestContextUtils.getLocaleResolver(request))*获得它们。

现在,我有点担心通过注入LocaleResolver获得HandlerInterceptor时是否忽略了陷阱或类似的东西? - 有任何想法吗?




@See:LocaleResolver
@See:LocaleChangeInterceptor
@See:RequestContext


* DispatcherServlet持有LocaleResolver的实例(通过注入或自行创建),并将其放置在每个请求的每个请求上下文中。

最佳答案

我认为没有任何陷阱。

RequestContextUtils.getLocaleResolver(HttpServletRequest)被实现为

public static LocaleResolver getLocaleResolver(HttpServletRequest request) {
    return (LocaleResolver) request.getAttribute(DispatcherServlet.LOCALE_RESOLVER_ATTRIBUTE);
}


换句话说,它是从HttpServletRequest属性获取的。使用DispatcherServlet.LOCALE_RESOLVER_ATTRIBUTE可以提示DispatcherServlet可能正在设置它。其initLocaleResolver()方法实现为

private void initLocaleResolver(ApplicationContext context) {
    try {
        this.localeResolver = context.getBean(LOCALE_RESOLVER_BEAN_NAME, LocaleResolver.class);
        if (logger.isDebugEnabled()) {
            logger.debug("Using LocaleResolver [" + this.localeResolver + "]");
        }
    }
    catch (NoSuchBeanDefinitionException ex) {
        // We need to use the default.
        this.localeResolver = getDefaultStrategy(context, LocaleResolver.class);
        if (logger.isDebugEnabled()) {
            logger.debug("Unable to locate LocaleResolver with name '" + LOCALE_RESOLVER_BEAN_NAME +
                    "': using default [" + this.localeResolver + "]");
        }
    }
}


因此,它是从上下文中获取其LocaleResolver或从某些默认配置生成它的,即。 DispatcherServlet.properties资源。

总之,如果您声明一个LocaleResolver bean,则用@Autowired注入它并从RequestContextUtils.getLocaleResolver(request)获取它都会得到相同的实例。请参见DispatcherServlet#doService(..)方法的

[...]
request.setAttribute(LOCALE_RESOLVER_ATTRIBUTE, this.localeResolver);
[...]




LocaleChangeInterceptor使用static实用程序,因为它不是Spring的bean。它是Spring MVC组件,不一定是WebApplicationContext的一部分,因此不属于其生命周期。它不能注入任何东西。

07-24 09:18