通过RequestContext和通过注入获取Spring LocalResolver?

时间:2014-02-14 10:45:11

标签: java spring spring-mvc locale

技术可以通过两种不同的方式获得LocaleResolver实例:

但哪种方式更好?


背景/上下文:

我已经实现了一个自定义的变体Locale Change Interceptor。这是HandlerInterceptor,有点像普通的LocaleChangeInterceptor,它使用注入方式获取LocaleResolver。它奏效了。

但是今天我已经仔细研究了LocaleChangeInterceptor。我注意到他们没有注入LocaleResolver但是从请求上下文(RequestContextUtils.getLocaleResolver(request))*中获取它们。

现在我有点担心,在LocaleResolver获取HandlerInterceptor注入{<1}}时,我是否忽略了陷阱或类似事情? - 任何想法?


* DispatcherServlet包含LocaleResolver的实例(通过注入或自己创建)并将它们放入每个请求的每个请求上下文中。

1 个答案:

答案 0 :(得分:1)

我认为没有任何陷阱。

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的一部分,因此不属于它的生命周期,即。它无法注入任何东西。