0

我发现了几个非常尴尬的问题,我花了 3 小时以上才解决。我想知道是否有人可以解释我为什么会这样。我相信他们都属于非常相同的背景,所以我有两个问题。我希望读者对我有耐心,因为这是科幻的既吓人又有趣的行为。

我只知道错误和解决方案,但直到我理解才满意:

  1. 我遵循的指导:拥有一个配置文件 - 仅在根customConfig中使用包扫描(通过 web.xml 中的映射声明),确保servlet-context.xml仅扫描控制器的包。所有其他上下文文件都通过customConfig开头的 import 指令导入。

1.1如果您以其他方式执行此操作,则会出错:依赖注入(各种组件)将因多个重叠配置包扫描而显着失败。

1.2以其他方式执行时出错:如果servlet-context.xml扫描相同的包,则在带有entityManagerFactory的上下文中的 transactionManager 服务请求期间的事务将失败。(即与您的customConfig扫描相同的服务包)

2:LocaleChangeInterceptor只能在servlet-context中声明- 在自定义根配置中不起作用,原因未知(即使在customConfig中为控制器包添加包扫描也不起作用,但是现在有趣的一点 -另一方面, SessionLocaleResolver将起作用好的,如果在自定义配置中定义!)

Q1:所以我应该责怪谁作为人类错误地添加了重叠的上下文组件包扫描,或者 Spring 解决这些冲突是否合乎逻辑?或者他们应该得到解决,但由于某种原因它对我不起作用?

当他告诉我最好不要碰弹簧配置,不要尝试改进它,也不要尝试更新它时,我观察了其他开发人员并微笑着。我笑了,现在我显然没有(我现在发现自己被这个 sf 配置暴力所暗示),毕竟你认为将所有内容都放在一个像servlet-context.xml这样的单个配置文件中是可以的吗?

Q2: LocaleChangeInterceptor背后的魔力是什么,我花了大约 5 个小时来修复它,直到将“try-and-fail”情绪转移到servlet-context 中并且它起作用了。

其次是要解决的纯粹谜团。customConfig里面没什么特别的

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">

<!-- 
<import resource="securityContext.xml"/>  -->
<import resource="jpaContext.xml"/> 


<context:annotation-config /> 
<context:component-scan base-package="com.org.app" />


<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
    <property name="basename" value="/WEB-INF/messages" />
    <property name="defaultEncoding" value="UTF-8"/>
</bean>


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

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

触发 ?lang=locale_LOCALE 请求后,什么都不会发生 - 没有错误,没有指示,应用程序将成功加载,页面将在相同的语言环境下重新加载。

但是,将此拦截器代码放在下面的 servlet-context.xml中将成功解析语言环境请求。

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context" 
    xmlns:p="http://www.springframework.org/schema/p"
    xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- DispatcherServlet Context: defines this servlet's request-processing 
        infrastructure -->

    <!-- Enables the Spring MVC @Controller programming model -->
    <annotation-driven />

    <context:component-scan base-package="com.org.app.controller" />


    <!-- Handles HTTP GET requests for /resources/** by efficiently serving 
        up static resources in the ${webappRoot}/resources directory -->
    <resources mapping="/resources/**" location="/resources/" />

    <!-- Resolves views selected for rendering by @Controllers to .jsp resources 
        in the /WEB-INF/views directory -->
    <beans:bean
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <beans:property name="prefix" value="/WEB-INF/views/" />
        <beans:property name="suffix" value=".jsp" />
    </beans:bean>


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


</beans:beans>
4

1 回答 1

1

您的LocalChangeInterceptorandLocaleResolver必须在servlet-context.xml. <context:annotation-driven />已经暗示使用<context:component-scan />

在您的根上下文中,您也在扫描@Controller您需要排除它们。

<context:component-scan base-package="com.org.app">
    <context:exclude-filter type="annotation" value="org.springframework.stereotype.Controller" />
</context:compoment-scan>

基本上所有与 web 相关的东西(以及 . 使用的东西DispatcherServlet)都必须由DispatcherServlet. 由于它的性质,它只会在它自己的本地应用程序上下文中查找它需要的 bean,而不是在其父级中查找。

这样做的原因是您可以拥有多个 DispatcherServlet,每个 DispatcherServlet 都有自己的配置,如果它从根应用程序上下文加载配置,则会中断。

于 2013-09-07T08:11:29.813 回答