这是一个错误。
经过对 spring.net 源代码的一些过度调试,我们发现:
- 对会话范围对象的支持由
spring.web
dll
- The
spring.web.mvc
dll不依赖于spring.web
- 这意味着,不可能实例化
MvcApplicationContext
可以解析会话范围的对象
以下解决方案显示了一个自定义的MvcApplicationContext
使用 spring.net 完全启用 MVC3 中的会话范围对象。
标准应用程序上下文无法解析 Web 范围的原因是它使用了该类RootObjectDefinition
维斯不知道scope
属性(在配置 xml 中)。这WebApplicationContext
相反实例化RootWebObjectDefinition
类型,知道范围。
The WebObjectsFactory
覆盖该方法CreateRootObjectDefinition
它返回的实例RootWebObjectDefinition
。这就是我们想要从应用程序上下文中返回的内容。这是通过重写方法来完成的CreateObjectsFactory
.
接下来,我们要重写的是方法CreateXmlObjectDefinitionReader
。当 spring 从配置中读取元数据时,它不会解析其他属性,例如scope
如果我们不选择特定的读者。因此我们将使用WebObjectDefinitionReader
在我们的应用程序上下文中。
对于会话范围对象的配置,您可以省略singleton
属性或将其显式设置为true
。否则具有价值false
会话范围肯定会被禁用。
EXAMPLE:
<objects xmlns="http://www.springframework.net">
<object id="shoppingCart" type="ShoppingCart, ..." singleton="true" scope="session" />
</objects>
分步解决方案:
- Create
MvcWebApplicationContext
继承自MvcApplicationContext
。您将需要重写上面提到的两个方法并创建默认构造函数。
- 创建一个
MvcWebContextHandler
继承自MvcContextHandler
。这将触发我们的自定义应用程序上下文将被使用。
- 在您的中使用自定义上下文处理程序
web.config
.
- 对于 IIS6 支持或 Visual Studio 内置 Web 服务器:添加
WebSupportModule
to system.web
部分。
- 对于 IIS7 支持:添加
WebSupportModule
to 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>
自定义应用程序上下文类:
public class MvcWebApplicationContext: MvcApplicationContext {
public MvcWebApplicationContext(string name, bool caseSensitive, params string[] configurationLocations)
: this(new MvcApplicationContextArgs(name, null, configurationLocations, null, caseSensitive))
{ }
public MvcWebApplicationContext(string name, bool caseSensitive, IApplicationContext parentContext, params string[] configurationLocations)
: this(new MvcApplicationContextArgs(name, parentContext, configurationLocations, null, caseSensitive))
{ }
public MvcWebApplicationContext(MvcApplicationContextArgs args)
: base(args)
{ }
public MvcWebApplicationContext(string name, bool caseSensitive, string[] configurationLocations, IResource[] configurationResources)
: this(new MvcApplicationContextArgs(name, null, configurationLocations, configurationResources, caseSensitive))
{ }
public MvcWebApplicationContext(params string[] configurationLocations)
: this(new MvcApplicationContextArgs(string.Empty, null, configurationLocations, null, false))
{ }
protected override XmlObjectDefinitionReader CreateXmlObjectDefinitionReader(DefaultListableObjectFactory objectFactory)
{
return new WebObjectDefinitionReader(GetContextPathWithTrailingSlash(), objectFactory, new XmlUrlResolver());
}
protected override DefaultListableObjectFactory CreateObjectFactory()
{
return new WebObjectFactory(GetContextPathWithTrailingSlash(), IsCaseSensitive);
}
private string GetContextPathWithTrailingSlash()
{
string contextPath = this.Name;
if (contextPath == DefaultRootContextName)
{
contextPath = "/";
}
else
{
contextPath = contextPath + "/";
}
return contextPath;
}
}
自定义上下文处理程序类:
public class MvcWebContextHandler : MvcContextHandler {
protected override Type DefaultApplicationContextType
{
get { return typeof(MvcWebApplicationContext); }
}
}
我们将此错误添加到 Spring.NET 的问题跟踪器中:https://jira.springsource.org/browse/SPRNET-1450 https://jira.springsource.org/browse/SPRNET-1450