我有一个 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>