"No message found under code" 如果 class 不在 servlet 上下文的基础包中。为什么?

"No message found under code" if class is not in base-package of servlet-context. Why?

它是与内部化相关的servlet-context的一部分。

<context:component-scan base-package="com.project.controllers" />

<interceptors>
    <beans:bean
        class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"
        p:paramName="lang" />

    <beans:bean
        class="org.springframework.web.servlet.theme.ThemeChangeInterceptor" />
</interceptors>

<!-- i18n -->
<beans:bean
    class="org.springframework.context.support.ReloadableResourceBundleMessageSource"
    id="messageSource" p:basenames="WEB-INF/i18n/messages, WEB-INF/i18n/application"
    p:fallbackToSystemLocale="false" />

<beans:bean class="org.springframework.web.servlet.i18n.CookieLocaleResolver"
    id="localResolver" p:cookieName="locale" />

根上下文:

<context:component-scan base-package="com.project"/>

<bean id="localeResolver"
    class="org.springframework.web.servlet.i18n.SessionLocaleResolver">
    <property name="defaultLocale" value="en" />
</bean>

如果我尝试在 jsp 页面或控制器包中获取消息,一切正常:

messageSource.getMessage("message.code", new Object[] {}, locale)

但是它不能在 servlet-context 中定义的包之外工作,尽管 messageSource bean 是自动装配的。

这是否意味着 root-context 具有默认的 messageSource 并且在 servlet-context 中它仅针对特定包被覆盖?

在 ServletContext 中为特定控制器定义的配置始终覆盖 rootContext 的配置。它也是根上下文私有的。

您放置在 servlet 上下文中的配置特定于该特定 servlet/controller。如果您需要国际化的全局功能,您应该在根上下文中定义 messageSource bean。

加载 ApplicationContext 时,它会自动搜索上下文中定义的 MessageSource bean。该 bean 必须具有名称 messageSource。如果找到这样的 bean,则对上述方法的所有调用都将委托给消息源。如果找不到消息源,ApplicationContext 会尝试查找包含同名 bean 的父级。如果是,它将使用该 bean 作为 MessageSource。 如果 ApplicationContext 找不到任何消息源,则会实例化一个空的 DelegatingMessageSource,以便能够接受对上面定义的方法的调用。