0

我有一个 Spring MVC 应用程序,并且我非常有信心了解我设置的所有各种配置,但是,在最近的一次练习中,我已经切换到使用基于纯注解的配置(除了安全配置)并且我有看到应用程序的行为发生了变化,这让我在几点上三思而后行。

主要的行为变化是,我的旧应用程序似乎正在运行 OpenSessionInView 类型模式 - 因为我的几个域对象是延迟加载元素,但这些元素仍然可以在事务/服务层类之外访问(例如我的控制器) - 切换到注释后,现在由于会话未在我的控制器层中打开而出现延迟加载错误,因此现在失败了。

下面是我一直在使用的配置 - 任何人都可以解释其中的哪一部分是我的应用程序之前显示的 OpenSessionInView 类型行为的原因吗?

应用上下文配置文件:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:mongo="http://www.springframework.org/schema/data/mongo"
    xmlns:cloud="http://schema.cloudfoundry.org/spring" xmlns:cache="http://www.springframework.org/schema/cache"
    xsi:schemaLocation="http://www.springframework.org/schema/aop 
    http://www.springframework.org/schema/aop/spring-aop.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   
    http://www.springframework.org/schema/jee 
    http://www.springframework.org/schema/jee/spring-jee.xsd
    http://www.springframework.org/schema/tx 
    http://www.springframework.org/schema/tx/spring-tx.xsd
    http://schema.cloudfoundry.org/spring 
    http://schema.cloudfoundry.org/spring/cloudfoundry-spring-0.7.xsd
    http://www.springframework.org/schema/mvc
    http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
    http://www.springframework.org/schema/cache 
    http://www.springframework.org/schema/cache/spring-cache.xsd">


    <context:property-placeholder location="classpath*:META-INF/spring/*.properties" />
    <context:spring-configured />
    <context:annotation-config />
    <mvc:annotation-driven />
    <aop:aspectj-autoproxy proxy-target-class="true" />
    <context:component-scan base-package="com.tmm.enterprise.adapter"></context:component-scan>
    <context:component-scan base-package="com.tmm.enterprise.service"></context:component-scan>
    <context:component-scan base-package="com.tmm.enterprise.helper"></context:component-scan>
    <context:component-scan base-package="com.tmm.enterprise.util"></context:component-scan>
    <context:component-scan base-package="com.tmm.enterprise.repository"></context:component-scan>
    <context:component-scan base-package="com.tmm.enterprise.core.dao"></context:component-scan>
    <context:component-scan base-package="com.tmm.enterprise.security.dao"></context:component-scan>


    <!--Http client -->
    <bean id="httpClient" class="org.apache.commons.httpclient.HttpClient">
        <property name="state" ref="httpState" />
    </bean>

    <!--Http state -->
    <bean id="httpState" factory-bean="httpStateFactory" factory-method="buildState"/> 

    <!--Http client -->
    <bean id="httpClientFactory"
        class="org.springframework.http.client.CommonsClientHttpRequestFactory">
        <constructor-arg ref="httpClient" />
    </bean>

    <!--RestTemplate -->
    <bean id="restTemplate" class="org.springframework.web.client.RestTemplate">
        <constructor-arg ref="httpClientFactory" />
    </bean>

    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
        lazy-init="default" autowire="default">
        <property name="driverClass" value="${database.driverClassName}" />
        <property name="jdbcUrl" value="${database.url}" />
        <property name="user" value="${database.username}" />
        <property name="password" value="${database.password}" />
    </bean>    


    <bean class="org.springframework.orm.jpa.JpaTransactionManager"
        id="transactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory" />
    </bean>

    <bean id="applicationController" class="com.tmm.enterprise.service.ApplicationService"></bean>

    <bean id="socialConfig"
        class="com.tmm.enterprise.configuration.SocialConfiguration"></bean>
    <bean id="cachingConfig"
        class="com.tmm.enterprise.configuration.CachingConfiguration"></bean>

    <tx:annotation-driven mode="aspectj"
        transaction-manager="transactionManager" proxy-target-class="true" />


    <bean
        class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
        id="entityManagerFactory">
        <property name="dataSource" ref="dataSource" />
        <property name="persistenceUnitName" value="persistenceUnit" />
    </bean>

    <bean id="geocoder" class="com.google.code.geocoder.Geocoder" />

    <bean id="validatorFactory" class="javax.validation.Validation"
        factory-method="buildDefaultValidatorFactory" />

    <bean id="validator" factory-bean="validatorFactory"
        factory-method="getValidator" />
</beans>

MVC 配置:

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

    <!-- The controllers are autodetected POJOs labeled with the @Controller annotation. -->
    <context:component-scan base-package="com.tmm.enterprise.controller" use-default-filters="false">
        <context:include-filter expression="org.springframework.stereotype.Controller" type="annotation"/>
    </context:component-scan>

    <!-- Turns on support for mapping requests to Spring MVC @Controller methods
         Also registers default Formatters and Validators for use across all @Controllers -->
    <mvc:annotation-driven/>

    <mvc:resources mapping="/resouces/**" location="/styles, /images, /javascript, /libs" />

    <!-- a higher value meaning greater in terms of sorting.  -->
    <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" p:order="3">
        <property name="alwaysUseFullPath" value="true" />
    </bean>

    <!-- register "global" interceptor beans to apply to all registered HandlerMappings -->
    <mvc:interceptors>
        <bean class="org.springframework.web.servlet.theme.ThemeChangeInterceptor"/>
        <bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" p:paramName="lang"/>
    </mvc:interceptors>

    <!-- selects a static view for rendering without the need for an explicit controller -->
    <mvc:view-controller path="/login"/>
    <!--mvc:view-controller path="/index"/-->
    <mvc:view-controller path="/uncaughtException"/>
    <mvc:view-controller path="/resourceNotFound"/>
    <mvc:view-controller path="/dataAccessFailure"/>
    <mvc:view-controller path="/jobs" view-name="jobsPage"/>
    <mvc:view-controller path="/applications" view-name="jobsPage"/>
    <mvc:view-controller path="/users" view-name="usersPage"/>
    <mvc:view-controller path="/companies" view-name="companiesPage"/>
    <mvc:view-controller path="/tos" view-name="tos"/>
    <mvc:view-controller path="/about" view-name="about"/>
    <mvc:view-controller path="/privacypolicy" view-name="privacyPolicy"/>
    <mvc:view-controller path="/sitemap.xml" view-name="sitemap"/>

    <!-- Resolves logical view names returned by Controllers to Tiles; a view
         name to resolve is treated as the name of a tiles definition -->
    <bean class="org.springframework.js.ajax.AjaxUrlBasedViewResolver" id="tilesViewResolver">
        <property name="viewClass" value="org.springframework.web.servlet.view.tiles2.TilesView"/>
    </bean>

    <!-- Configures the Tiles layout system -->
    <bean class="org.springframework.web.servlet.view.tiles2.TilesConfigurer" id="tilesConfigurer">
        <property name="definitions">
            <list>
                <value>/WEB-INF/layouts/layouts.xml</value>
                <!-- Scan views directory for Tiles configurations -->
                <value>/WEB-INF/views/**/views.xml</value>
            </list>
        </property>
    </bean>

    <!-- Resolves localized messages*.properties and application.properties files in the application to allow for internationalization. 
        The messages*.properties files translate Roo generated messages which are part of the admin interface, the application.properties
        resource bundle localizes all application specific messages such as entity names and menu items. -->
    <bean class="org.springframework.context.support.ReloadableResourceBundleMessageSource" id="messageSource" p:basenames="WEB-INF/i18n/application" p:fallbackToSystemLocale="false"/>

    <!-- store preferred language configuration in a cookie -->
    <bean class="org.springframework.web.servlet.i18n.CookieLocaleResolver" id="localeResolver" p:cookieName="locale"/> 

    <!-- resolves localized <theme_name>.properties files in the classpath to allow for theme support -->
    <bean class="org.springframework.ui.context.support.ResourceBundleThemeSource" id="themeSource"/>

    <!-- store preferred theme configuration in a cookie -->
    <bean class="org.springframework.web.servlet.theme.CookieThemeResolver" id="themeResolver" p:cookieName="theme" p:defaultThemeName="standard"/>

    <!-- This bean resolves specific types of exceptions to corresponding logical - view names for error views. 
         The default behaviour of DispatcherServlet - is to propagate all exceptions to the servlet container: 
         this will happen - here with all other types of exceptions. -->
    <bean class="com.tmm.enterprise.controller.exception.NerdExceptionHandler" p:defaultErrorView="uncaughtException">
        <property name="exceptionMappings">
            <props>
                <prop key=".DataAccessException">dataAccessFailure</prop>
                <prop key=".NoSuchRequestHandlingMethodException">resourceNotFound</prop>
                <prop key=".TypeMismatchException">resourceNotFound</prop>
                <prop key=".MissingServletRequestParameterException">resourceNotFound</prop>
            </props>
        </property>
    </bean>


    <!-- Controllers --> 
    <bean id="connectController" class="com.tmm.enterprise.controller.ConnectController"></bean>

    <!-- allows for integration of file upload functionality -->
    <bean class="org.springframework.web.multipart.commons.CommonsMultipartResolver" id="multipartResolver"/>

    <bean id="ajaxViewResolver"
        class="com.tmm.enterprise.views.AjaxViewResolver">
        <property name="ajaxView">
            <bean class="com.tmm.enterprise.views.AjaxView" />
        </property>
        <property name="ajaxPrefix" value="ajax_"></property>
    </bean>

    <bean id="editableViewResolver"
        class="com.tmm.enterprise.views.EditableViewResolver">
        <property name="editableView">
            <bean class="com.tmm.enterprise.views.EditableView" />
        </property>
        <property name="editablePrefix" value="editable_"></property>
    </bean>
</beans>
4

1 回答 1

1

OpenSessionInView(Hibernate)/OpenEntityManagerInView(JPA) 行为通常是 web.xml 中定义的过滤器的一部分,但也可以使用拦截器来完成,如本答案中所述。您可以将 OpenEntityManagerInViewInterceptor 用于 JPA。

<mvc:interceptors>
    <bean class="org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor">
        <property name="sessionFactory">
            <ref local="sessionFactory" />
        </property>
    </bean>
</mvc:interceptors>
于 2013-05-27T12:53:16.893 回答