会话范围bean可以与Spring Session和GemFire一起使用吗?

时间:2017-08-14 12:03:38

标签: spring-session spring-data-gemfire

可以"会话"范围bean与 Spring Session 和Pivotal GemFire一起使用?

使用 Spring Session 进行" session"范围bean, Spring 为此bean创建额外的HttpSession。这是一个现存的问题吗?

这是什么解决方案?

1 个答案:

答案 0 :(得分:4)

...关于

  

会话范围bean可以与Spring Session和GemFire一起使用吗?

是!

事实上,哪个底层&#34;提供商&#34;并不重要。与 Spring Session 一起使用。例如,可以使用Spring Session with GemFire/Geodedocs)或Spring Session with Redisdocs)等,它们的工作方式相同(以相同的方式)。< / p>

至于......

  

如果对会话作用域使用Spring Session,Spring会为这个bean创建额外的HttpSession,这是一个现存的问题吗?

嗯, 完全正确。

您必须了解这里的基础技术以及它们如何协同工作,包括 Spring Session Spring Framework Servlet Framework ,您的 Web容器(例如Tomcat),它受Java EE Servlet 规范中指定的合同以及您可能已应用的任何其他技术的约束(例如< em> Spring Security的 Web支持)。

如果我们深入了解 Spring的架构/基础架构,您将开始了解它的工作原理,工作原理以及您的特定声明(&#34; Spring为此bean创建额外 HttpSession &#34;)正确。

首先, Spring Session 注册一个重要的 Servlet Filtero.s.session.web.http.SessionRepositoryFilter

有许多不同的方法可以做到这一点,javax.servlet.Filter Javadoc 实质上暗示这是通过Web应用程序&#34; 部署描述符&#34;

当然,考虑到我们今天的配置选项,Web应用程序部署描述符的定义非常松散,但我们通常都知道这意味着web.xml。但是,这不是我们可以配置Web应用程序ServletContext的唯一方式。

Spring 使用 Servlet 支持基于web.xml部署描述符以及 JavaConfig ( 3.0+)API。

web.xml中,您register(对于example Spring Frameworks&#39; o.s.web.filter.DelegatingFilterProxy,代表实际javax.servlet.Filter 1}}实现(当 Spring Session 正在运行时,当然是o.s.session.web.http.SessionRepositoryFilter),它也被声明/定义为&#34; bean &#34; Spring 容器中的第一个this,然后是this)。这是必要的,以便自动连接(注入)适当的 Spring Session o.s.session.SessionRepository实现(也是容器中定义的 Spring 托管bean,例如{ {3}})知道如何将(HTTP)Session状态管理委托给底层&#34;提供商&#34;。

JavaConfig 方法中,注册是通过核心 Spring Framework的 Redis概念执行的。阅读Javadoc了解更多详情。

嗯, Spring Session 提供了WebApplicationInitializer初始化(HTTP)会话管理o.s.web.WebApplicationInitializer。通常,在使用 Spring o.s.session.web.context.AbstractHttpSessionApplicationInitializer和/或Java-based Container Configuration方法时,开发人员会创建一个扩展此 Spring Session 的类class和Annotation configuration基础会话管理提供者的必要配置(例如连接标准);对于register(另见example)。 Config类为this@EnableRedisHttpSession annotated Spring @Configuration类声明/定义相应的 Spring &#34;提供商&#34;的会话 SessionRepository实施(例如,再次imports),这是 Servlet Filter所需的(再次SessionRepositoryFilter)。

如果你看一下 Spring Session AbstractHttpSessionApplicationInitializer的作用,你会看到{{3>} Spring Session ,{{1} },间接通过 Spring Framework&#39> <{em> SessionRepositoryFilter ...来自插入,然后是Redis,然后是registers,最后是here

如您所见, Servlet DelegatingFilterProxy链中的 Spring Session SessionRepositoryFilterhere。由于here中的参数为&#34; isMatchAfter &#34;。

Filters被否定。

这是必不可少的,因为 Spring Session&#39> !insertBeforeOtherFilters positioned first o.s.session.web.http.SessionRepositoryFilterjavax.servlet.http.HttpServletRequest。具体来说,通过替换javax.servlet.http.HttpServletResponse Spring Session 可以提供由{em> Spring Session <支持的javax.servlet.http.HttpServletRequest(当调用javax.servlet.http.HttpSession时)的实现/ em>和开发人员的选择提供商(例如Redis,GemFire),首先是 Spring Session 的全部目的。

因此, Servlet HttpServletRequest.getSession(..)在任何框架代码(例如 Spring Framework&#39> s 会话范围的bean基础结构)之前看到HTTP请求/响应,特别是在任何Web应用程序FiltersControllers之前,请查看HTTP请求/响应。

因此,当核心 Spring Framework的会话作用域bean基础结构看到(HTTP) Servlet 请求/响应时,它会看到 Spring会话交给它,这只是一个由 Spring Session 支持的常规Servlets接口(例如javax.servlet)的实现。

查看核心 Spring Framework&#39> javax.servlet.FilterRegistration.Dynamic.addMappingForUrlPatterns(dispatcherTypes, isMatchAfter, urlPatterns...)&#34; custom&#34;实现(处理 Spring 容器中声明/定义的会话范围bean的bean引用/ bean生命周期),扩展HttpSession,你看到它只是委托给replaces类。该类主要由 Spring&#39> <{em> o.s.web.context.request.AbstractRequestAttributesScope创建,并根据&#34;提供的&#34;定义其所有操作(例如o.s.web.context.request.SessionScope)。由所讨论的bean(定义)定义的范围。有关详细信息,请参阅o.s.web.context.request.SessionRequestAttributes。因此bean被添加到适当的HTTP会话中。

当然, Spring setAttribute(name, value, scope) DispatcherServlet在第一个HTTP请求上,但不是没有 Spring Session的基础设施知道它,因为 Spring 在这种情况下使用的是由{em> Spring Session&#39> &#34; javax.servlet.http.HttpSession&#支持的javax.servlet.http.HttpSession的实现34。

另外,source也表示Session是&#34; 允许&#34;如果它还不存在就被创建! Servlet 容器根本不会为每个HTTP请求创建新的HTTP会话,只要可以从HTTP请求确定会话ID(通过URL注入完成... {{1或者通常使用cookie)。有关详细信息,请参阅"will" create a new

无论如何,对整个故事唯一的另一个警告是,你需要确保,特别是对于GemFire,......

  1. Spring &#34; session&#34;容器中定义的scoped bean可以使用Java Serialization或getSession(true)中的1个进行序列化。这包括bean引用(其他bean,对象类型等),除非那些&#34;引用&#34;声明为HttpSession。注意:我并不完全确定基于GemFire Reflection的PDX序列化方法是完全&#34;意识到&#34; &#34; transient &#34;领域。要注意这一点。

  2. 您必须确保会话中序列化的类位于GemFire Servers类路径中。

  3. 目前我是javax.servlet.HttpServletRequest.getSession(boolean)用于支持PDX的Spring Session Data Geode / GemFire,但 尚未提供。

    无论如何,我希望这有助于清理泥泞的水域。我知道要消化很多,但这一切都应该像用户期望的那样工作。

    我还要补充一点,我还没有测试过这个。但是,在查看代码之后,我很确定这应该可行。

    我有GemFire's serialization strategies在不久的将来添加测试和样本以涵盖这种情况。

    干杯! -John