Spring配置问题不容易找到解决方案

时间:2013-09-07 05:44:40

标签: spring spring-mvc configuration

我发现了几个非常尴尬的问题,需要我3小时才能解决。我想知道是否有人能解释我为什么会这样。我相信它们都属于非常相同的背景,所以我有两个问题。我希望读者对我有耐心,这对于sf来说既是令人生畏又有趣的行为。

我只知道错误和解决方案,但在我理解之前不满意:

  1. 我遵循的指导:有一个配置文件 - 仅在您的根目录 customConfig 中使用包扫描(通过web.xml中的映射声明),确保 servlet-context.xml 仅扫描控制器的包。所有其他上下文文件在 customConfig 的最开头通过import指令导入。
  2. 1.1 如果您以其他方式执行此操作时出错:依赖注入(各种组件)会因多次重叠配置包扫描而显着失败。

    1.2 如果您以其他方式执行此操作时出错:如果 servlet-context.xml entityManagerFactory 的上下文中,事务管理器的服务请求期间的事务将失败>扫描同一个包裹。 (即与 customConfig 扫描相同的服务包)

    2: LocaleChangeInterceptor 只能在 servlet-context 中声明 - 在自定义root配置中不起作用,原因未知(即使添加包扫描也不起作用)对于 customConfig 中的控制器包,但是如果在自定义配置中定义,现在有趣的位 - SessionLocaleResolver 将正常工作!)

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

    我观察了开发人员,当他告诉最好不要触摸弹簧配置,也不尝试改进它,也不尝试更新它时微笑。我笑了,现在我显然没有(我现在发现自己被这个sf配置暴力所暗示),所有这些之后你认为可以将所有内容放在一个配置文件中,例如 servlet-context.xml

    第二季度: LocaleChangeInterceptor 背后的魔力是什么,我花了大约5个小时来修复它,直到只是将“尝试并失败”的情绪转移到 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请求什么都不会发生 - 没有错误,没有指示,app会成功加载,页面只会在同一个区域设置下重新加载。

    但是,将此拦截器代码放在下面的 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>
    

1 个答案:

答案 0 :(得分:1)

必须在LocalChangeInterceptor中定义LocaleResolverservlet-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>

基本上所有与网络相关的内容(以及DispatcherServlet使用的内容)都必须由DispatcherServlet加载。由于它的性质,它只会查看它所需的bean的本地应用程序上下文,而不是它的父项。

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