可能这是一个愚蠢的问题,我只是不明白Spring和IIS是如何工作的,但我们试一试。
我是ASP.NET的新手,据我所知,会话处理类似于Apache / PHP:
会话在浏览器的选项卡之间共享,但不在不同浏览器之间共享。即如果我在Firefox中打开我的页面并在购物车中放入一些东西,那么购物车仍然会在另一个标签中包含我的商品,但是在Internet Explorer中打开同一页面应该会显示一个空的购物车。
但是我无法使用Spring.NET重现这种行为。
我用购物车对象创建了一个hello-world,在会话范围中注明:
<objects xmlns="http://www.springframework.net">
<object id="shoppingCart" type="DemoShop.Models.Cart.ShoppingCart, DemoShop" singleton="true" scope="session" />
</objects>
如果我在购物车中添加了某些内容,它会在任何标签页和浏览器中保留。所以这看起来好像这个对象是一个真正的单例,因此在IIS应用程序的运行时期间是持久的。
我知道,你要说的是:为什么我在spring配置中使用属性singleton="true"
?好吧,如果我删除它或将其设置为false
,那么该对象将不会在会话中保留,但会在每个请求上重新创建,从而丢失它的数据。
Spring.NET文档根本没有谈到MVC上下文中的singleton
属性,我花了一些时间才弄明白,似乎需要使用MVC3。
我能够使用
成功创建应用程序范围对象<object id="..." type="..., ..." singleton="true" scope="application" />
并使用
请求范围对象<object id="..." type="..., ..." scope="request" />
或
<object id="..." type="..., ..." singleton="false" scope="request" />
但是保留singleton
属性,无论我在scope
属性中实际注意到哪个范围,都要将我的对象放在请求范围内。
我的猜测是,会话实际上并没有在Firefox和IE之间共享,但是cart对象只是在应用程序范围内,因为我使用的是错误的方式。
任何人都可以给我建议或提示我做错了什么,或者这是IIS7中的问题?
答案 0 :(得分:2)
这是一个错误。
经过对spring.net源代码的一些过度调试后,我们发现:
spring.web
dll spring.web.mvc
dll不依赖于spring.web
MvcApplicationContext
以下解决方案显示了一个自定义MvcApplicationContext
,它使用spring.net在MVC3中完全启用了会话范围对象。
标准应用程序上下文无法解析Web范围的原因是它使用类RootObjectDefinition
而不知道scope
属性(在config xml中)。而WebApplicationContext
实例化RootWebObjectDefinition
类型,它们知道范围。
WebObjectsFactory
会覆盖返回CreateRootObjectDefinition
实例的方法RootWebObjectDefinition
。这是我们想要从应用程序上下文返回的那个。这是通过覆盖方法CreateObjectsFactory
完成的。
接下来,我们必须覆盖方法CreateXmlObjectDefinitionReader
。当spring从配置中读取元数据时,如果我们不接受特定的读者,它将不会解析其他属性,如scope
。因此,我们将在应用程序上下文中使用WebObjectDefinitionReader
。
对于会话范围对象的配置,您可以省略singleton
属性或将其明确设置为true
。否则值为false
,会话范围将被禁用。
实施例
<objects xmlns="http://www.springframework.net">
<object id="shoppingCart" type="ShoppingCart, ..." singleton="true" scope="session" />
</objects>
分步解决方案:
MvcWebApplicationContext
的{{1}}。您需要覆盖上面提到的两种方法并创建默认构造函数。MvcApplicationContext
的{{1}}。这将触发我们的自定义应用程序上下文的使用。MvcWebContextHandler
。MvcContextHandler
添加到web.config
部分。WebSupportModule
添加到system.web
部分。的web.config:
WebSupportModule
自定义应用程序上下文类:
system.webserver
自定义上下文处理程序类:
<configSections>
<sectionGroup name="spring">
<section name="context" type="YourNamspace.MvcWebContextHandler, YourAssembly"/>
....
</sectionGroup>
....
</configSections>
<!-- IIS6 -->
<system.web>
<httpModules>
<add name="Spring" type="Spring.Context.Support.WebSupportModule, Spring.Web"/>
</httpModules>
</system.web>
<!-- IIS7 -->
<system.webServer>
<validation validateIntegratedModeConfiguration="false"/>
<modules runAllManagedModulesForAllRequests="true" >
<add name="Spring" type="Spring.Context.Support.WebSupportModule, Spring.Web"/>
</modules>
</system.webServer>
我们在Spring.NET的问题跟踪器中添加了这个bug: https://jira.springsource.org/browse/SPRNET-1450