3. HttpSession 集成

Spring Session 提供与 .这意味着开发人员 可以用 Spring Session 支持的实现替换该实现。javax.servlet.http.HttpSessionHttpSessionspring-doc.cn

Spring Session 支持插入多个不同的数据存储提供程序(例如,如 Apache Geode) 为了管理国家。HttpSessionspring-doc.cn

3.1. 为什么选择Spring Session和HttpSession?

我们已经提到 Spring Session 提供了与 的透明集成,但是有什么好处 我们能摆脱这一切吗?HttpSessionspring-doc.cn

  • HttpSession - 使 能够被集群化(即复制的 以实现高可用性),而无需绑定到特定于应用程序容器的解决方案。HttpSessionspring-doc.cn

  • REST API - 允许在协议标头中提供会话 ID,以便与 RESTful API 一起使用。spring-doc.cn

  • WebSocket - 提供在接收 WebSocket 消息时保持活动状态的能力。HttpSessionspring-doc.cn

  • WebSession - 允许以应用程序容器中立的方式替换 Spring WebFlux。WebSessionspring-doc.cn

3.2. 使用 Apache Geode 进行 HttpSession 管理

Apache Geode 与 Spring Session 一起使用时,Web 应用程序的 Web 应用程序可以替换为由 Apache Geode 管理的集群实现 并使用 Spring Session 的 API 方便地访问。javax.servlet.http.HttpSessionspring-doc.cn

使用 Apache Geode 管理会话状态的两种最常见拓扑包括:spring-doc.cn

此外,Apache Geode 还支持使用 WAN 拓扑进行站点到站点复制。 配置和使用 Apache Geode 的 WAN 功能的能力独立于 Spring Session、 并且超出了本文档的范围。spring-doc.cn

有关使用 Spring Data for Apache Geode 配置 Apache Geode WAN 功能的更多详细信息 可以在这里找到。spring-doc.cn

3.2.1. Apache Geode 客户端-服务器

客户端-服务器拓扑可能是 在 Spring Session 中使用 Apache Geode 作为提供程序时,用户最常见的配置选择,因为 与应用程序相比,Apache Geode 服务器具有明显不同且独特的 JVM 堆要求。 使用 Client-Server 拓扑使应用程序能够独立管理(例如复制)应用程序状态 从其他应用程序进程。spring-doc.cn

在 Client-Server 拓扑中,使用 Spring Session 的应用程序将打开与远程集群的 1 个或多个连接 的 Apache Geode 服务器,这些服务器将管理对所有状态的访问。HttpSessionspring-doc.cn

您可以使用以下任一方式配置客户端-服务器拓扑:spring-doc.cn

Apache Geode Client-Server 基于 Java 的配置

本节介绍如何配置 Apache Geode 的客户端-服务器拓扑以管理状态 使用基于 Java 的配置。HttpSessionspring-doc.cn

带有 Apache Geode(客户端-服务器)的 HttpSession 提供了一个工作示例,演示如何 将 Spring Session 与 Apache Geode 集成,以使用 Java 配置管理状态。您可以阅读 通过下面的基本集成步骤,但我们鼓励您按照详细的 'HttpSession' 进行操作 与 Apache Geode (客户端-服务器) 指南集成时。HttpSession
Spring Java 配置

添加所需的依赖项和存储库声明后,我们可以创建 Spring 配置。 Spring 配置负责创建一个 Servlet,该 Servlet 替换为 Spring Session 和 Apache Geode 支持的实现。FilterHttpSessionspring-doc.cn

客户端配置

添加以下 Spring 配置:spring-doc.cn

@ClientCacheApplication(name = "SpringSessionDataGeodeJavaConfigSampleClient",
	readTimeout = 15000, retryAttempts = 1, subscriptionEnabled = true) (1)
@EnableGemFireHttpSession(poolName = "DEFAULT") (2)
public class ClientConfig extends ClientServerIntegrationTestsSupport {

	@Bean
	ClientCacheConfigurer gemfireServerReadyConfigurer( (3)
			@Value("${spring.data.gemfire.cache.server.port:40404}") int cacheServerPort) {

		return (beanName, clientCacheFactoryBean) -> waitForServerToStart("localhost", cacheServerPort);
	}
}
1 首先,我们通过对类进行注释,将 Web 应用程序声明为 Apache Geode 缓存客户端 跟。此外,我们还调整了一些基本的 “DEFAULT” 设置(例如 )。ClientConfig@ClientCacheApplicationPoolreadTimeout
2 @EnableGemFireHttpSession创建一个名为 的 Spring Bean,该 Bean 实现 .过滤器将 替换为 Spring Session 提供的实现 并由 Apache Geode 提供支持。此外,该配置还将创建必要的客户端(默认情况下,“ClusteredSpringSessions”,这是一个)按名称对应于同一服务器端。所有会话状态都通过数据访问操作从客户端发送到服务器。 客户端使用 “DEFAULT” 。springSessionRepositoryFilterjavax.servlet.FilterHttpSessionRegionPROXYRegionRegionRegionRegionPool
3 然后,我们等待确保 Apache Geode Server 已启动并运行,然后再继续。这才真正有用 用于自动化 (集成) 测试目的。
在典型的 Apache Geode 生产部署中,集群可能包括数百或数千个 的服务器(也称为数据节点)中,客户端更常见的是连接到 1 个或多个正在运行的 Apache Geode 定位器 在同一个集群中。Locator 将有关集群中可用服务器的元数据传递给客户端,单个 server load 以及哪些服务器具有感兴趣的客户端数据,这对于 Direct 尤为重要。 单跳数据访问和延迟敏感型应用程序。有关客户端/服务器部署的更多详细信息,请参阅 Apache Geode 用户指南。
有关配置 Spring Data Geode 的更多信息,请参阅参考指南

该注解使开发人员能够配置 Spring Session 的某些方面 和 Apache Geode 开箱即用,使用以下属性:@EnableGemFireHttpSessionspring-doc.cn

  • clientRegionShortcut- 使用 ClientRegionShortcut 在客户端上指定 Apache Geode 数据管理策略(默认值为 )。此属性仅在配置 client 时使用。PROXYRegionspring-doc.cn

  • indexableSessionAttributes- 按名称标识 Session 应为查询目的编制索引的属性。 只有 name 显式标识的 Session 属性才会被索引。spring-doc.cn

  • maxInactiveIntervalInSeconds- 控制 HttpSession 空闲超时过期时间(默认为 30 分钟)。spring-doc.cn

  • poolName- 用于将客户端连接到服务器集群的专用 Apache Geode 的名称。 仅当应用程序是高速缓存客户端时,才使用此属性。默认为 。PoolgemfirePoolspring-doc.cn

  • regionName- 指定用于存储和管理状态的 Apache Geode 的名称 (默认为 “ClusteredSpringSessions”)。RegionHttpSessionspring-doc.cn

  • serverRegionShortcut- 使用 RegionShortcut 指定服务器上的 Apache Geode 数据管理策略(默认值为 )。此属性仅在配置 server 时使用 或者当采用 P2P 拓扑时。PARTITIONRegionsspring-doc.cn

请务必记住,如果客户端是 或 ,则 Apache Geode 客户端名称必须与同名服务器匹配。客户端和服务器名称 如果用于存储会话状态的客户端是 ,则不需要匹配。但是,请记住 该会话状态不会传播到服务器,并且您将失去使用 Apache Geode 的所有好处 要在分布式 复制方式。RegionRegionRegionPROXYCACHING_PROXYRegionRegionLOCAL
服务器配置

到目前为止,我们只介绍了等式的一面。我们还需要一个 Apache Geode 服务器,以便我们的缓存客户端与之通信 并将会话状态发送到服务器进行管理。spring-doc.cn

在此示例中,我们将使用以下 Java 配置来配置和运行 Apache Geode 服务器:spring-doc.cn

@CacheServerApplication(name = "SpringSessionDataGeodeJavaConfigSampleServer") (1)
@EnableGemFireHttpSession(maxInactiveIntervalInSeconds = 30) (2)
public class GemFireServer {

	public static void main(String[] args) {
		new AnnotationConfigApplicationContext(GemFireServer.class).registerShutdownHook();
	}
}
1 首先,我们使用 Comments 来简化 peer cache 实例的创建 包含用于缓存客户端连接的。@CacheServerApplicationCacheServer
2 (可选)然后,对类进行注释以创建必要的 服务器端(默认为 “ClusteredSpringSessions”)用于存储状态。此步骤为 可选,因为 Session 可以手动创建,可能使用外部方式。 使用方便快捷。GemFireServer@EnableGemFireHttpSessionRegionHttpSessionRegion@EnableGemFireHttpSession
Apache Geode 客户端-服务器基于 XML 的配置

本节介绍如何配置 Apache Geode 的客户端-服务器拓扑以管理状态 使用基于 XML 的配置。HttpSessionspring-doc.cn

使用 XML 的 HttpSession 与 Apache Geode(客户端-服务器)提供了一个工作示例 演示如何将 Spring Session 与 Apache Geode 集成以使用 XML 管理状态 配置。您可以阅读下面的集成基本步骤,但我们鼓励您按照 在详细的 'HttpSession' with Apache Geode (Client-Server) using XML Guide 中集成时 您自己的应用程序。HttpSession
Spring XML 配置

添加所需的依赖项和存储库声明后,我们可以创建 Spring 配置。 Spring 配置负责创建一个,该配置将 替换为 Spring Session 和 Apache Geode 支持的实现。ServletFilterjavax.servlet.http.HttpSessionspring-doc.cn

客户端配置

添加以下 Spring 配置:spring-doc.cn

	<context:annotation-config/>

	<context:property-placeholder/>

	<bean class="sample.client.ApacheGeodeServerWebApplicationInitializer"/>
	<bean class="sample.client.ClientServerReadyBeanPostProcessor"/>

	(1)
	<util:properties id="gemfireProperties">
		<prop key="log-level">${spring.data.gemfire.cache.log-level:error}</prop>
	</util:properties>

	(2)
	<gfe:client-cache properties-ref="gemfireProperties" pool-name="gemfirePool"/>

	(3)
	<gfe:pool read-timeout="15000" retry-attempts="1" subscription-enabled="true">
		<gfe:server host="localhost" port="${spring.data.gemfire.cache.server.port:40404}"/>
	</gfe:pool>

	(4)
	<bean class="org.springframework.session.data.gemfire.config.annotation.web.http.GemFireHttpSessionConfiguration"
		  p:poolName="DEFAULT"/>
1 (可选)首先,我们可以包含一个 Bean,以使用 Pivotal GemFire Properties 配置 Apache Geode 的某些方面。在这种情况下,我们只是 使用特定于应用程序的 System 属性设置 Apache Geode 的 “log-level”,默认为 “warning” 如果未指定。PropertiesClientCache
2 我们必须创建一个 Apache Geode 的实例。我们使用 .ClientCachegemfireProperties
3 然后,我们配置一个连接,以便与客户端/服务器拓扑中的 Apache Geode 服务器通信。 在我们的配置中,我们对超时、连接数等使用合理的设置。此外,我们的已配置为直接连接到服务器(使用嵌套元素)。PoolPoolgfe:server
4 最后,注册一个 bean 以启用 Spring Session 功能。GemFireHttpSessionConfiguration
在典型的 Apache Geode 生产部署中,集群可能包括数百或数千个 的服务器(也称为数据节点)中,客户端更常见的是连接到 1 个或多个正在运行的 Apache Geode 定位器 在同一个集群中。Locator 将有关集群中可用服务器的元数据传递给客户端,单个 server load 以及哪些服务器具有感兴趣的客户端数据,这对于 Direct 尤为重要。 单跳数据访问和延迟敏感型应用程序。有关客户端/服务器部署的更多详细信息,请参阅 Apache Geode 用户指南。
有关为 Apache Geode 配置 Spring Data 的更多信息,请参阅参考指南
服务器配置

到目前为止,我们只介绍了等式的一面。我们还需要一个 Apache Geode 服务器,以便我们的缓存客户端与之通信 并将会话状态发送到服务器进行管理。spring-doc.cn

在此示例中,我们将使用以下 XML 配置来启动 Apache Geode 服务器:spring-doc.cn

	<context:annotation-config/>

	<context:property-placeholder/>

	(1)
	<util:properties id="gemfireProperties">
		<prop key="name">SpringSessionDataGeodeSampleXmlServer</prop>
		<prop key="log-level">${spring.data.gemfire.cache.log-level:error}</prop>
	</util:properties>

	(2)
	<gfe:cache properties-ref="gemfireProperties"/>

	(3)
	<gfe:cache-server port="${spring.data.gemfire.cache.server.port:40404}"/>

	(4)
	<bean class="org.springframework.session.data.gemfire.config.annotation.web.http.GemFireHttpSessionConfiguration"
		  p:maxInactiveIntervalInSeconds="30"/>
1 (可选)首先,我们可以包含一个 bean,以使用 Pivotal GemFire Properties 配置 Apache Geode 对等节点的某些方面。在这种情况下,我们只是 使用特定于应用程序的 System 属性设置 Apache Geode 的 “log-level”,默认为 “warning” 如果未指定。PropertiesCache
2 我们必须配置 Apache Geode 对等实例。我们使用 Apache Geode 属性对其进行初始化。Cache
3 接下来,我们为缓存客户端定义一个具有合理配置并供其使用的 应用程序连接到服务器并发送会话状态。CacheServerbind-addressport
4 最后,我们启用我们在客户端 XML 配置中声明的相同 Spring Session 功能 通过注册 的实例,但我们设置了会话过期超时 设置为 30 秒。我们稍后会解释这意味着什么。GemFireHttpSessionConfiguration

Apache Geode Server 使用以下方法进行引导:spring-doc.cn

@Configuration (1)
@ImportResource("META-INF/spring/session-server.xml") (2)
public class GemFireServer {

	public static void main(String[] args) {
		new AnnotationConfigApplicationContext(GemFireServer.class).registerShutdownHook();
	}
}
与其使用方法定义简单的 Java 类,不如考虑使用 Spring Boot。main
1 该注解使用 7.9. 基于注解的容器配置[Spring 的注解配置支持]。@Configuration
2 首先,配置来自文件。META-INF/spring/session-server.xml
XML Servlet 容器初始化

我们的 Spring XML 配置创建了一个名为 Implements interface 的 Spring bean。bean 负责将 替换为 Spring Session 和 Apache Geode 提供的自定义实现。springSessionRepositoryFilterjavax.servlet.FilterspringSessionRepositoryFilterjavax.servlet.http.HttpSessionspring-doc.cn

为了让我们发挥它的魔力,我们需要指示 Spring 加载 我们的配置文件。Filtersession-client.xmlspring-doc.cn

我们使用以下配置执行此操作:spring-doc.cn

来源/main/webapp/WEB-INF/web.xml
<context-param>
	<param-name>contextConfigLocation</param-name>
	<param-value>/WEB-INF/spring/session-client.xml</param-value>
</context-param>
<listener>
	<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

ContextLoaderListener读取上下文参数值并选取我们的session-client.xml配置文件。contextConfigLocationspring-doc.cn

最后,我们需要确保我们的 Servlet 容器(即 Tomcat)对每个请求都使用我们的容器。springSessionRepositoryFilterspring-doc.cn

以下代码片段为我们执行了最后一步:spring-doc.cn

来源/main/webapp/WEB-INF/web.xml
<filter>
	<filter-name>springSessionRepositoryFilter</filter-name>
	<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
	<filter-name>springSessionRepositoryFilter</filter-name>
	<url-pattern>/*</url-pattern>
	<dispatcher>REQUEST</dispatcher>
	<dispatcher>ERROR</dispatcher>
</filter-mapping>

DelegatingFilterProxy 将按名称查找 bean 并将其转换为 .对于每个 HTTP 请求, 调用,它将 .springSessionRepositoryFilterFilterDelegatingFilterProxyspringSessionRepositoryFilterspring-doc.cn

3.2.2. Apache Geode 点对点 (P2P)

一种不太常见的方法是将 Spring Session 应用程序配置为 Apache Geode 集群中的对等成员 使用点对点 (P2P) 拓扑。 在此配置中,Spring Session 应用程序将是 Apache Geode 中的实际服务器(或数据节点) cluster 的 CLUSTER,而不仅仅是像以前那样只是一个缓存客户端。spring-doc.cn

这种方法的一个优点是应用程序接近应用程序的状态(即它的数据), 尤其是国家。但是,还有其他有效的方法可以实现类似的 依赖于数据的计算,例如使用 Apache Geode 的 Function Execution。 在以下情况下可以使用 Apache Geode 的任何其他功能 Apache Geode 在 Spring Session 中充当提供程序。HttpSessionspring-doc.cn

P2P 拓扑结构对于测试目的以及更小、更专注和独立的应用程序非常有用。 例如微服务架构中的那些,并且肯定会改善您的应用程序的感知 延迟和吞吐量需求。spring-doc.cn

您可以使用以下任一方式配置点对点 (P2P) 拓扑:spring-doc.cn

Apache Geode 点对点 (P2P) 基于 Java 的配置

本节介绍如何配置 Apache Geode 的点对点 (P2P) 拓扑以管理状态 使用基于 Java 的配置。HttpSessionspring-doc.cn

HttpSession 与 Apache Geode (P2P) 提供了一个工作示例,演示如何 将 Spring Session 与 Apache Geode 集成,以使用 Java 配置管理状态。您可以阅读 通过下面的基本集成步骤,但我们鼓励您按照详细的 'HttpSession' 进行操作 与 Apache Geode (P2P) 指南集成时。HttpSession
Spring Java 配置

添加所需的依赖项和存储库声明后,我们可以创建 Spring 配置。spring-doc.cn

Spring 配置负责创建一个,该配置将 替换为 Spring Session 和 Apache Geode 支持的实现。ServletFilterjavax.servlet.http.HttpSessionspring-doc.cn

添加以下 Spring 配置:spring-doc.cn

@PeerCacheApplication(name = "SpringSessionDataGeodeJavaConfigP2pSample", logLevel = "error") (1)
@EnableGemFireHttpSession(maxInactiveIntervalInSeconds = 30) (2)
public class Config {

}
1 首先,我们使用 annotation 来简化 peer cache 实例的创建。@PeerCacheApplication
2 然后,对类进行 Comments 以创建用于存储状态的必要服务器端(默认情况下为“ClusteredSpringSessions”)。Config@EnableGemFireHttpSessionRegionHttpSession
有关为 Apache Geode 配置 Spring Data 的更多信息,请参阅参考指南

该注解使开发人员能够配置 Spring Session 的某些方面 和 Apache Geode 开箱即用,使用以下属性:@EnableGemFireHttpSessionspring-doc.cn

  • clientRegionShortcut- 使用 ClientRegionShortcut 在客户端上指定 Apache Geode 数据管理策略(默认值为 )。此属性仅在配置 client 时使用。PROXYRegionspring-doc.cn

  • indexableSessionAttributes- 按名称标识 Session 应为查询目的编制索引的属性。 只有 name 显式标识的 Session 属性才会被索引。spring-doc.cn

  • maxInactiveIntervalInSeconds- 控制 HttpSession 空闲超时过期时间(默认为 30 分钟)。spring-doc.cn

  • poolName- 用于将客户端连接到服务器集群的专用 Apache Geode 的名称。 仅当应用程序是高速缓存客户端时,才使用此属性。默认为 。PoolgemfirePoolspring-doc.cn

  • regionName- 指定用于存储和管理状态的 Apache Geode 的名称 (默认为 “ClusteredSpringSessions”)。RegionHttpSessionspring-doc.cn

  • serverRegionShortcut- 使用 RegionShortcut 指定服务器上的 Apache Geode 数据管理策略(默认值为 )。此属性仅在配置 server 时使用 或者当采用 P2P 拓扑时。PARTITIONRegionsspring-doc.cn

Java Servlet 容器初始化

我们的<<[httpsession-spring-java-configuration-p2p,Spring Java Configuration>>创建了一个名为 的 Spring Bean,它实现了 .豆子 负责将 替换为由 Spring Session 和 Apache Geode。springSessionRepositoryFilterjavax.servlet.FilterspringSessionRepositoryFilterjavax.servlet.http.HttpSessionspring-doc.cn

为了让我们发挥它的魔力, Spring 需要加载我们的 class。我们还需要确保我们的 Servlet 容器(即 Tomcat)在每个 HTTP 请求上都使用 our。FilterConfigspringSessionRepositoryFilterspring-doc.cn

幸运的是,Spring Session 提供了一个名为 步骤非常简单。AbstractHttpSessionApplicationInitializerspring-doc.cn

您可以在下面找到一个示例:spring-doc.cn

来源/main/java/sample/Initializer.java
public class Initializer extends AbstractHttpSessionApplicationInitializer { (1)

	public Initializer() {
		super(Config.class); (2)
	}
}
类的名称 () 无关紧要。重要的是,我们将 .InitializerAbstractHttpSessionApplicationInitializer
1 第一步是扩展 .这确保了一个名为 Spring bean 的 Servlet 容器被注册到我们的 Servlet 容器中,并用于每个 HTTP 请求。AbstractHttpSessionApplicationInitializerspringSessionRepositoryFilter
2 AbstractHttpSessionApplicationInitializer还提供了一种机制,可轻松允许 Spring 加载 我们的班级。Config
基于 Apache Geode 对等 (P2P) XML 的配置

本节介绍如何配置 Apache Geode 的点对点 (P2P) 拓扑以管理状态 使用基于 XML 的配置。HttpSessionspring-doc.cn

使用 XML 的 HttpSession with Apache Geode (P2P) 提供了一个工作示例,演示如何 将 Spring Session 与 Apache Geode 集成,以使用 XML 配置管理状态。您可以阅读 通过下面的基本集成步骤,但我们鼓励您按照详细的 'HttpSession' 进行操作 与 Apache Geode (P2P) 集成时,使用 XML 指南HttpSession
Spring XML 配置

添加所需的依赖项和存储库声明后,我们可以创建 Spring 配置。spring-doc.cn

Spring 配置负责创建一个,该配置将 替换为 Spring Session 和 Apache Geode 支持的实现。ServletFilterjavax.servlet.http.HttpSessionspring-doc.cn

添加以下 Spring 配置:spring-doc.cn

来源/main/webapp/WEB-INF/spring/session.xml
<context:annotation-config/>

<context:property-placeholder/>

(1)
<util:properties id="gemfireProperties">
	<prop key="name">SpringSessionDataGeodeXmlP2pSample</prop>
	<prop key="log-level">${spring.data.gemfire.cache.log-level:error}</prop>
</util:properties>

(2)
<gfe:cache properties-ref="gemfireProperties"/>

(3)
<bean class="org.springframework.session.data.gemfire.config.annotation.web.http.GemFireHttpSessionConfiguration"
	p:maxInactiveIntervalInSeconds="30"/>
1 (可选)首先,我们可以包含一个 Bean,以使用 VMware Tanzu GemFire Properties 配置 Apache Geode 对等节点的某些方面。在这种情况下,我们只是 使用特定于应用程序的 System 属性设置 Apache Geode 的 “log-level”,默认为 “warning” 如果未指定。PropertiesCache
2 我们必须配置 Apache Geode 对等实例。我们使用 Apache Geode 属性对其进行初始化。Cache
3 最后,我们通过注册 .GemFireHttpSessionConfiguration
有关为 Apache Geode 配置 Spring Data 的更多信息,请参阅参考指南
XML Servlet 容器初始化

Spring XML 配置创建了一个名为 的 Spring Bean,该 Bean 实现 .该 Bean 负责将 替换为由 Spring Session 和 Apache Geode 支持的自定义实现。springSessionRepositoryFilterjavax.servlet.FilterspringSessionRepositoryFilterjavax.servlet.http.HttpSessionspring-doc.cn

为了让我们发挥它的魔力,我们需要指示 Spring 加载我们的配置文件。Filtersession.xmlspring-doc.cn

我们使用以下配置执行此操作:spring-doc.cn

来源/main/webapp/WEB-INF/web.xml
<context-param>
	<param-name>contextConfigLocation</param-name>
	<param-value>
		/WEB-INF/spring/*.xml
	</param-value>
</context-param>
<listener>
	<listener-class>
		org.springframework.web.context.ContextLoaderListener
	</listener-class>
</listener>

ContextLoaderListener 读取 context 参数值并选取我们的 session.xml 配置文件。contextConfigLocationspring-doc.cn

最后,我们需要确保我们的 Servlet 容器(即 Tomcat)对每个 HTTP 请求都使用我们的容器。springSessionRepositoryFilterspring-doc.cn

以下代码片段为我们执行了最后一步:spring-doc.cn

来源/main/webapp/WEB-INF/web.xml
<filter>
	<filter-name>springSessionRepositoryFilter</filter-name>
	<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
	<filter-name>springSessionRepositoryFilter</filter-name>
	<url-pattern>/*</url-pattern>
	<dispatcher>REQUEST</dispatcher>
	<dispatcher>ERROR</dispatcher>
</filter-mapping>

DelegatingFilterProxy 将按名称查找 bean 并将其转换为 .对于每个 HTTP 请求 ,委托给 .springSessionRepositoryFilterFilterDelegatingFilterProxyspringSessionRepositoryFilterspring-doc.cn

3.3. 使用带有属性的 Apache Geode 配置管理HttpSession

虽然 Comments 在开始使用 Spring Session 时易于使用和方便 和 Apache Geode 在 Spring Boot 应用程序中迁移时,您很快就会遇到限制 环境转换为另一个环境,例如,从 DEV 迁移到 QA 再到 PROD 时。@EnableGemFireHttpSessionspring-doc.cn

使用 annotation 属性,无法将配置从一个 环境到另一个。因此,Spring Session for Apache Geode 引入了众所周知的、记录在案的属性 对于所有 annotation 属性。@EnableGemFireHttpSession@EnableGemFireHttpSessionspring-doc.cn

表 4.注释属性的已知、有文档记录的属性。@EnableGemFireHttpSession
财产 Annotation 属性 描述 违约

spring.session.data.gemfire.cache.client.pool.namespring-doc.cn

EnableGemFireHttpSession.poolNamespring-doc.cn

客户端区域存储/访问 Session 状态使用的专用池的名称。spring-doc.cn

gemfirePoolspring-doc.cn

spring.session.data.gemfire.cache.client.region.shortcutspring-doc.cn

EnableGemFireHttpSession.clientRegionShortcutspring-doc.cn

在客户端-服务器拓扑中设置客户端区域数据管理策略。spring-doc.cn

ClientRegionShortcut.代理spring-doc.cn

spring.session.data.gemfire.cache.server.region.shortcutspring-doc.cn

EnableGemFireHttpSession.serverRegionShortcutspring-doc.cn

在对等 (P2P) 拓扑中设置对等区域数据管理策略。spring-doc.cn

RegionShortcut.PARTITION 分区spring-doc.cn

spring.session.data.gemfire.session.attributes.indexablespring-doc.cn

EnableGemFireHttpSession.indexableSessionAttributesspring-doc.cn

要在 Session 区域中编制索引的 Session 属性的逗号分隔列表。spring-doc.cn

spring.session.data.gemfire.session.expiration.bean-namespring-doc.cn

EnableGemFireHttpSession.sessionExpirationPolicyBeanNamespring-doc.cn

实现过期策略的 Spring 容器中的 Bean 的名称spring-doc.cn

spring.session.data.gemfire.session.expiration.max-inactive-interval-secondsspring-doc.cn

EnableGemFireHttpSession.maxInactiveIntervalInSecondsspring-doc.cn

会话过期超时(秒)spring-doc.cn

1800spring-doc.cn

spring.session.data.gemfire.session.region.namespring-doc.cn

EnableGemFireHttpSession.regionNamespring-doc.cn

用于存储和访问 Session 状态的客户端或对等区域的名称。spring-doc.cn

ClusteredSpringSessions 集群spring-doc.cn

spring.session.data.gemfire.session.serializer.bean-namespring-doc.cn

EnableGemFireHttpSession.sessionSerializerBeanNamespring-doc.cn

实现序列化策略的 Spring 容器中的 Bean 的名称spring-doc.cn

SessionPdxSerializerspring-doc.cn

所有属性也都记录在 annotation 属性 Javadoc 中。@EnableGemFireHttpSession

因此,在使用 Apache Geode 时,调整 Spring Session 的配置非常简单 作为您的提供商,如下所示:spring-doc.cn

@SpringBootApplication
@ClientCacheApplication
@EnableGemFireHttpSession(maxInactiveIntervalInSeconds = 900)
class MySpringSessionApplication {
  // ...
}

然后,在 :application.propertiesspring-doc.cn

#application.properties
spring.session.data.gemfire.cache.client.region.shortcut=CACHING_PROXY
spring.session.data.gemfire.session.expiration.max-inactive-internval-seconds=3600

显式定义的任何属性都会覆盖相应的 annotation 属性。@EnableGemFireHttpSessionspring-doc.cn

在上面的示例中,即使 annotation 属性 设置为秒或 15 分钟,则相应的属性属性 (即 ) 覆盖该值并将 Expiration (过期时间) 设置为 seconds (秒) 或 60 分钟。EnableGemFireHttpSessionmaxInactiveIntervalInSeconds900spring.session.data.gemfire.session.expiration.max-inactive-interval-seconds3600spring-doc.cn

请记住,属性会在运行时覆盖 annotation 属性值。

3.3.1. 属性的属性

您甚至可以变得更复杂,并使用其他属性配置您的属性,如下所示:spring-doc.cn

#application.properties
spring.session.data.gemfire.session.expiration.max-inactive-internval-seconds=${app.geode.region.expiration.timeout:3600}

此外,您可以使用 Spring 配置文件根据环境改变过期超时(或其他属性) 或您的应用程序,或者您的应用程序要求的任何标准。spring-doc.cn

属性占位符和嵌套是核心 Spring Framework 的一个功能,并不特定于 Spring Session 或 Spring Session for Apache Geode。

3.4. 使用 Apache Geode 和 Configurer 配置 ManagementHttpSession

除了属性之外,Spring Session for Apache Geode 还允许您调整 使用界面的 Apache Geode 的 Spring Session。该接口定义了一个 包含可覆盖的每个 annotation 属性的默认方法的 Contract 调整配置。SpringSessionGemFireConfigurer@EnableGemFireHttpSessionspring-doc.cn

这在概念上类似于 Spring Web MVC 的 Configurer 接口 (例如),它调整 Web 应用程序的 配置,例如配置异步支持。声明和实现 a 的优点是,它允许您对配置进行编程控制。这在您需要的情况下非常有用 轻松表达确定是否应应用配置的复杂条件逻辑。SpringSessionGemFireConfigurero.s.web.servlet.config.annotation.WebMvcConfigurerConfigurerspring-doc.cn

例如,要像以前一样调整 client Region data management policy (客户端区域数据管理策略) 和 Session expiration timeout (会话过期超时),请执行以下操作: 使用以下内容:spring-doc.cn

@Configuration
class MySpringSessionConfiguration {

  @Bean
  SpringSessionGemFireConfigurer exampleSpringSessionGemFireConfigurer() {

    return new SpringSessionGemFireConfigurer() {

      @Override
      public ClientRegionShortcut getClientRegionShortcut() {
        return ClientRegionShortcut.CACHING_PROXY;
      }

      @Override
      public int getMaxInactiveIntervalInSeconds() {
        return 3600;
      }
    };
  }
}

当然,这个例子不是很有创意。您肯定可以使用更复杂的逻辑来确定 每个 configuration 属性的 configuration。spring-doc.cn

您可以根据需要进行复杂操作,例如根据其他属性实现 使用 Spring 的 Comments,如下所示:Configurer@Valuespring-doc.cn

@Configuration
class MySpringSessionConfiguration {

  @Bean
  @Primary
  @Profile("production")
  SpringSessionGemFireConfigurer exampleSpringSessionGemFireConfigurer(
      @Value("${app.geode.region.data-management-policy:CACHING_PROXY}") ClientRegionShortcut shortcut,
      @Value("${app.geode.region.expiration.timeout:3600}") int timeout) {

    return new SpringSessionGemFireConfigurer() {

      @Override
      public ClientRegionShortcut getClientRegionShortcut() {
        return shortcut;
      }

      @Override
      public int getMaxInactiveIntervalInSeconds() {
        return timeout;
      }
    };
  }
}
Spring Boot 将自动解析 Comments 属性占位符值或 SPEL 表达式。 但是,如果您不使用 Spring Boot,则必须显式注册静态 bean 定义。@ValuePropertySourcesPlaceholderConfigurer

但是,您一次只能在 Spring 容器中声明 1 个 bean,除非 您还在使用 Spring 配置文件,或者已将多个 bean 中的 1 个标记为 primary 通过使用 Spring 的 context Comments 来获取。SpringSessionGemFireConfigurerSpringSessionGemFireConfigurer@Primaryspring-doc.cn

3.4.1. 配置优先级

A 优先于注释属性 或任何已知且记录在 案的 Spring Session for Apache Geode 属性 (例如) 在 Spring Boot 中定义SpringSessionGemFireConfigurer@EnableGemFireHttpSessionspring.session.data.gemfire.session.expiration.max-inactive-interval-secondsapplication.properties.spring-doc.cn

如果您的 Web 应用程序使用了 1 种以上的配置方法,则以下优先级将适用:spring-doc.cn

  1. SpringSessionGemFireConfigurer“已实现” 回调方法spring-doc.cn

  2. 记录的 Spring Session for Apache Geode 属性(参见相应的注释 属性 Javadoc;例如@EnableGemFireHttpSessionspring.session.data.gemfire.session.region.name)spring-doc.cn

  3. @EnableGemFireHttpSession注释属性spring-doc.cn

Spring Session for Apache Geode 小心翼翼地只应用来自 Bean 的配置 在 Spring 容器中声明。SpringSessionGemFireConfigurerspring-doc.cn

在上面的示例中,由于您没有实现该方法,因此 Apache Geode 区域的名称 管理状态将不由 Configurer 决定。getRegionName()HttpSessionspring-doc.cn

例如,请考虑以下配置:spring-doc.cn

Spring Session for Apache Geode 配置示例
@ClientCacheApplication
@EnableGemFireHttpSession(
    maxInactiveIntervalInSeconds = 3600,
    poolName = "DEFAULT"
)
class MySpringSessionConfiguration {

  @Bean
  SpringSessionGemFireConfigurer sessionExpirationTimeoutConfigurer() {

    return new SpringSessionGemFireConfigurer() {

      @Override
      public int getMaxInactiveIntervalInSeconds() {
        return 300;
      }
    };
  }
}

此外,请考虑以下 Spring Boot 文件:application.propertiesspring-doc.cn

  1. Spring Bootapplication.propertiesspring-doc.cn

spring.session.data.gemfire.session.expiration.max-inactive-interval-seconds = 900
spring.session.data.gemfire.session.region.name = Sessions

Session expiration timeout (会话过期超时) 将为 300 秒或 5 分钟,覆盖 (即 ) 为 900 秒,或 15 分钟, 以及 3600 秒,即 1 小时。spring.session.data.gemfire.session.expiration.max-inactive-interval-seconds@EnableGemFireHttpSession.maxInactiveIntervalInSecondsspring-doc.cn

由于 “sessionExpirationTimeoutConfigurer” Bean 不会覆盖该方法,因此 Session Region name 将由属性设置为 “Sessions” 的属性 (i.e.) 确定, 这将覆盖 implicit annotation 属性的默认值 “ClusteredSpringSessions” 的 ClusteredSpringSessions 中。getRegionName()spring.session.data.gemfire.session.region.name@EnableGemFireHttpSession.regionNamespring-doc.cn

annotation 属性的值 “DEFAULT” 将决定存储池的名称 在客户端和服务器之间发送 Region 操作以管理服务器上的 Session 状态时使用,因为 设置了相应的属性(即 spring.session.data.gemfire.cache.client.pool.name'),也未设置 该方法被“sessionExpirationTimeoutConfigurer”Bean 覆盖。@EnableGemFireHttpSession.poolNameSpringSessionGemFireConfigurer.getPoolName()spring-doc.cn

最后,用于管理 Session 状态的客户端区域将具有 的数据管理策略 ,默认 value (未显式设置的 annotation 属性),或者 是此属性的相应属性(即 )。 并且,由于该方法未被覆盖,因此使用默认值。PROXY@EnableGemFireHttpSession.clientRegionShortcutspring.session.data.gemfire.cache.client.region.shortcutSpringSessionConfigurer.getClientRegionShortcut()spring-doc.cn

3.5. Apache Geode 过期

默认情况下,Apache Geode 使用 过期超时为 30 分钟,并将 INVALIDATE 条目作为操作。这意味着当用户的 Session 保持非活动状态时 (即空闲)超过 30 分钟,Session 将过期并失效,用户必须开始新的 Session 以便继续使用该应用程序。spring-doc.cn

但是,如果您对会话状态管理和过期以及使用 默认的空闲超时 (TTI) 过期策略不足以满足您的用例 (UC) 需求?spring-doc.cn

现在,Spring Session for Apache Geode 支持特定于应用程序的自定义过期策略。作为应用程序 开发者,你可以指定自定义规则来管理由 Spring Session 管理的 Session 的过期,由 Apache Geode 的 Apache。spring-doc.cn

Spring Session for Apache Geode 提供了新的 Strategy 接口。SessionExpirationPolicyspring-doc.cn

SessionExpirationPolicy 接口
@FunctionalInterface
interface SessionExpirationPolicy {

    // determine timeout for expiration of individual Session
    Optional<Duration> determineExpirationTimeout(Session session);

    // define the action taken on expiration
    default ExpirationAction getExpirationAction() {
        return ExpirationAction.INVALIDATE;
    }

    enum ExpirationAction {

        DESTROY,
        INVALIDATE

    }
}

您实施此接口以指定应用程序所需的 Session 过期策略,然后注册 实例作为 Spring 应用程序上下文中的 Bean。spring-doc.cn

使用 annotation, 属性配置 实现 Session 过期的自定义应用程序策略和规则的 Bean。@EnableGemFireHttpSessionsessionExpirationPolicyBeanNameSessionExpirationPolicyspring-doc.cn

例如:spring-doc.cn

习惯SessionExpirationPolicy
class MySessionExpirationPolicy implements SessionExpirationPolicy {

    public Duration determineExpirationTimeout(Session session) {
        // return a java.time.Duration specifying the length of time until the Session should expire
    }
}

然后,在您的 application 类中,简单地声明以下内容:spring-doc.cn

自定义配置SessionExpirationPolicy
@SpringBootApplication
@EnableGemFireHttpSession(
    maxInactiveIntervalInSeconds = 600,
    sessionExpirationPolicyBeanName = "expirationPolicy"
)
class MySpringSessionApplication {

    @Bean
    SessionExpirationPolicy expirationPolicy() {
        return new MySessionExpirationPolicy();
    }
}
或者,可以使用该属性配置 Bean 的名称,也可以通过在 Spring 容器中声明 Bean 并覆盖该方法来配置 Bean 的名称。SessionExpirationPolicyspring.session.data.gemfire.session.expiration.bean-nameSpringSessionGemFireConfigurergetSessionExpirationPolicyBeanName()

您只需要实现方法 它封装了规则以确定 Session 何时到期。Session 的过期超时 表示为 of ,它指定 Session 过期之前的时间长度。determineExpirationTimeout(:Session):Optional<Duration>Optionaljava.time.Durationspring-doc.cn

该方法可以是特定于 Session 的,并且可能会随着每次调用而更改。determineExpirationTimeoutspring-doc.cn

或者,您可以实现该方法以指定 Session 过期时执行的操作。默认情况下, 区域条目(即 Session)无效。另一种选择是在过期时销毁 Region Entry, 这将删除键 (Session ID) 和值 (Session)。Invalidate 仅删除该值。getActionspring-doc.cn

在后台,它被改编成 Apache Geode CustomExpiry 接口的实例。 然后,将此 Spring Session 对象设置为 Session Region 的自定义条目空闲超时过期策略SessionExpirationPolicyCustomExpiry
在确定过期期间,每次运行过期线程时,都会为区域中的每个条目(即 Session)调用该方法,这反过来又会 调用我们的方法。 返回的 S 将转换为秒,并在从 CustomExpiry.getExpiry(..) 方法调用返回的 ExpirationAttributes 中用作过期超时。CustomExpiry.getExpiry(:Region.Entry<String, Session>):ExpirationAttributesSessionExpirationPolicy.determineExpirationTimout(:Session):Optional<Duration>java.time.Duration
Apache Geode 的过期线程每秒运行一次,评估区域中的每个条目(即会话) 以确定条目是否已过期。您可以使用该属性控制过期线程数。有关更多详细信息,请参阅 Apache Geode 文档gemfire.EXPIRY_THREADS

3.5.1. Expiration Timeout 配置

如果要根据自定义的过期超时 annotation、attribute 或 相应的属性 那么你的自定义实现也可以实现 interface.SessionExpirationPolicy@EnableGemFireHttpSessionmaxInactiveIntervalInSecondsspring.session.data.gemfire.session.expiration.max-inactive-interval-secondsSessionExpirationPolicySessionExpirationTimeoutAwarespring-doc.cn

接口定义为:SessionExpirationTimeoutAwarespring-doc.cn

SessionExpirationTimeoutAware 接口
interface SessionExpirationTimeoutAware {

    void setExpirationTimeout(Duration expirationTimeout);

}

当您的自定义实现还实现了接口 则 Spring Session for Apache Geode 将为您的实现提供来自注释、属性或属性(如果已设置)的值,或者来自 Spring 应用程序上下文中声明的任何 Bean 的值,作为 .SessionExpirationPolicySessionExpirationTimeoutAware@EnableGemFireHttpSessionmaxInactiveIntervalInSecondsspring.session.data.gemfire.session.expiration.max-inactive-interval-secondsSpringSessionGemFireConfigurerjava.time.Durationspring-doc.cn

如果使用了 1 个以上的配置选项,则以下顺序优先:spring-doc.cn

  1. SpringSessionGemFireConfigurer.getMaxInactiveIntervalInSeconds()spring-doc.cn

  2. spring.session.data.gemfire.session.expiration.max-inactive-interval-seconds财产spring-doc.cn

  3. @EnableGemFireHttpSession注释, 属性maxInactiveIntervalInSecondsspring-doc.cn

3.5.2. 固定超时过期

为了更加方便,Spring Session for Apache Geode 提供了固定持续时间过期(或核心 Spring Session Issue #922 中描述的“绝对会话超时”)的接口实现。SessionExpirationPolicyspring-doc.cn

在某些情况下,例如出于安全原因,可能需要在固定 时间长度 (例如每小时),无论用户的 Session 是否仍处于活动状态。spring-doc.cn

Spring Session for Apache Geode 提供了开箱即用的实现 对于此确切的用例 (UC)。除了处理固定期限到期外,还要小心地仍然考虑 并应用默认的 Idle Expiration 超时。FixedTimeoutSessionExpirationPolicyspring-doc.cn

例如,考虑这样一个场景:用户登录,开始一个会话,处于活动状态 10 分钟,然后离开 让 Session 处于空闲状态。如果固定持续时间过期超时设置为 60 分钟,但空闲过期 超时仅设置为 30 分钟,并且用户未返回,则 Session 应在 40 分钟后过期 而不是 60 分钟,此时将发生固定持续时间过期。spring-doc.cn

相反,如果用户忙碌了整整 40 分钟,从而使 Session 保持活动状态,从而避免了 30 分钟 idle expiration timeout,然后离开,那么我们的固定持续时间过期超时应该开始并过期 用户的 Session 时间,即使用户的空闲过期超时要到 70 分钟才会发生 in(40 分钟 (活动) + 30 分钟 (空闲) = 70 分钟)。spring-doc.cn

嗯,这正是 this 所做的。FixedTimeoutSessionExpirationPolicyspring-doc.cn

要配置 ,请执行以下操作:FixedTimeoutSessionExpirationPolicyspring-doc.cn

固定持续时间到期配置
@SpringBootApplication
@EnableGemFireHttpSession(sessionExpirationPolicyBeanName = "fixedTimeoutExpirationPolicy")
class MySpringSessionApplication {

    @Bean
    SessionExpirationPolicy fixedTimeoutExpirationPolicy() {
        return new FixedTimeoutSessionExpirationPolicy(Duration.ofMinutes(60L));
    }
}

在上面的示例中,在 Spring 应用程序上下文中将 声明为 bean 并使用 60 分钟的固定持续时间过期超时进行初始化。因此,用户的 Session 将 在空闲超时(默认为 30 分钟)或固定超时(配置为 60 分钟)后过期, 哪个先发生。FixedTimeoutSessionExpirationPolicyspring-doc.cn

还可以使用 适用于 Apache Geode 的 Spring 会话。此 BPP 包装 实施中特定于任何数据存储 ,仅评估 Sessions 在访问时过期。此方法与基础数据存储无关 因此可以与任何 Spring Session 提供程序一起使用。到期确定完全基于 Session 属性和 required 指定固定持续时间 过期超时。FixedDurationExpirationSessionRepositoryBeanPostProcessorSessionRepositoryFixedDurationExpirationSessionRepositorycreationTimejava.time.Duration
不应在严格的过期超时情况下使用 ,例如 当 Session 必须在固定持续时间过期超时后立即过期时。此外,与 的 , 不采用空闲过期 timeout 的考虑。也就是说,在确定过期超时时,它只使用固定持续时间 对于给定的 Session。FixedDurationExpirationSessionRepositoryFixedTimeoutSessionExpirationPolicyFixedDurationExpirationSessionRepository

3.5.3. 链接SessionExpirationPolicy

使用复合软件设计模式,您可以将一组实例视为单个实例,其功能就像在链中一样,就像 Servlet 过滤器本身。SessionExpirationPolicyspring-doc.cn

复合软件设计模式是一种功能强大的模式,由 , 提供支持,只需返回 of from 方法。SessionExpirationPolicy@FunctionalInterfaceOptionaljava.time.DurationdetermineExpirationTimeoutspring-doc.cn

这允许每个组合仅在 可以由此实例确定。或者,此实例可以传送到合成中的下一个实例,也可以链接,直到返回非空过期超时,或者最终返回 不返回过期超时。SessionExpirationPolicyDurationSessionExpirationPolicyspring-doc.cn

事实上,这个策略是由 内部使用的,如果空闲超时发生在固定超时之前,它将返回。通过返回 无过期超时,Apache Geode 将遵循默认的、配置的条目空闲超时过期策略 在管理 Session 状态的区域上。FixedTimeoutSessionExpirationPolicyOptional.empty()spring-doc.cn

3.6. Apache Geode 序列化

为了在客户端和服务器之间传输数据,或者在对等节点之间分发和复制数据 在集群中,数据必须序列化。在这种情况下,有问题的数据是 Session 的状态。spring-doc.cn

每当 Session 在 client/server 拓扑中被持久化或访问时,Session 的状态都会通过网络发送。 通常,启用了 Spring Session 的 Spring Boot 应用程序将是集群中服务器的客户端 Apache Geode 节点。spring-doc.cn

在服务器端,Session 状态可能分布在集群中的多个服务器(数据节点)之间进行复制 数据,并保证 Session 状态的高可用性。使用 Apache Geode 时,可以对数据进行分区, 或 sharded,并且可以指定 redundancy-level 。当分发数据以进行复制时,它还必须 serialized 在集群中的 Peer 节点之间传输 Session 状态。spring-doc.cn

开箱即用的 Apache Geode 支持 Java 序列化Java 序列化有很多优点, 例如处理对象图中的循环,或者被任何用 Java 编写的应用程序普遍支持。 但是,Java 序列化非常冗长,并不是最有效的在线格式。spring-doc.cn

因此,Apache Geode 提供了自己的序列化框架来序列化 Java 类型:spring-doc.cn

3.6.1. Apache Geode 序列化背景

如上所述,Apache Geode 提供了 2 个额外的序列化框架:数据序列化和 PDX 序列化spring-doc.cn

数据序列化

数据序列化是一种非常有效的格式(即快速紧凑),与 Java 序列化相比开销很小。spring-doc.cn

通过发送 只发送实际更改的数据位,而不是发送整个对象,这肯定会减少 除了在持久保存数据时减少 IO 量外,还关注通过网络发送的数据量 或溢出到磁盘。spring-doc.cn

但是,每当数据通过网络传输或持久化/溢出到 并从磁盘访问,因为接收端执行反序列化。事实上,无论何时使用 Delta Propagation,都必须在接收端对对象进行反序列化,以便应用 “delta”。Apache Geode 适用 deltas 的 deltas 方法。显然,你不能 在序列化对象上调用方法。org.apache.geode.Deltaspring-doc.cn

PDX

另一方面,PDX 代表便携式数据交换,它保留了发送数据的形式。 例如,如果客户端以 PDX 格式将数据发送到服务器,则服务器会将数据保留为 PDX 序列化字节 并将它们存储在数据访问操作所针对的缓存中。Regionspring-doc.cn

此外,PDX,顾名思义,是“可移植的”,这意味着它支持 Java 和本地语言客户端。 例如 C、C++ 和 C# 客户端,以对同一数据集进行互操作。spring-doc.cn

PDX 甚至允许对序列化的字节执行 OQL 查询,而不会导致对象被反序列化 首先,以便评估查询谓词并执行查询。这可以从 Apache Geode 开始实现 维护一个 “Type Registry”,其中包含被序列化和存储的对象的类型元数据 使用 PDX 的 Apache Geode。spring-doc.cn

但是,可移植性确实有成本,其开销略高于数据序列化。尽管如此,PDX 还很遥远 比 Java 序列化更高效、更灵活,Java 序列化将类型元数据存储在对象的序列化字节中 而不是像 Apache Geode 在使用 PDX 时那样在单独的类型注册表中。spring-doc.cn

PDX 不支持 Delta。从技术上讲,PDX 可序列化对象可以通过实现 org.apache.geode.Delta 接口,并且只有 “delta” 将是 发送的,即使在 PDX 的上下文中也是如此。但是,必须反序列化 PDX 序列化对象才能应用增量。 请记住,调用一个方法来应用 delta,这首先违背了使用 PDX 的目的。spring-doc.cn

在开发管理 {data-store-name} 集群中数据的 Native Client(例如 C)时,甚至在混合 具有 Java 客户端的 Native Client,通常不会在 Classpath 上提供任何关联的 Java 类型 集群中 的服务器。使用 PDX,无需在 Classpath 上提供 Java 类型,并且许多 仅开发和使用 Native Client 来访问存储在 {data-store-name} 中的数据的用户将不会提供任何 Java 类型。spring-doc.cn

Apache Geode 还支持序列化为 PDX 或从 PDX 序列化的 JSON。在这种情况下,Java 类型很可能不会 在服务器 Classpath 上提供,因为支持 JSON 的许多不同语言(例如 JavaScript、Python、Ruby)可以是 与 Apache Geode 一起使用。spring-doc.cn

尽管如此,即使 PDX 正在运行,用户也必须注意不要在集群中的服务器上导致 PDX 序列化对象 进行反序列化。spring-doc.cn

例如,考虑对序列化为 PDX...spring-doc.cn

@Region("People")
class Person {

  private LocalDate birthDate;
  private String name;

  public int getAge() {
    // no explicit 'age' field/property in Person
    // age is just implemented in terms of the 'birthDate' field
  }
}

随后,如果 OQL 查询在对象上调用方法,例如:Personspring-doc.cn

SELECT * FROM /People p WHERE p.age >= 21spring-doc.cn

然后,这将导致 PDX 序列化对象被反序列化,因为 不是 , 而是一个包含基于另一个字段 的计算的方法(即 )。同样,调用 OQL 查询中的任何方法(如 )都将导致反序列化的发生 也。PersonagePersonPersonbirthDatejava.lang.ObjectObject.toString()spring-doc.cn

Apache Geode 确实提供读取序列化配置设置,以便可能在 内部调用的任何缓存操作不会导致 PDX 序列化对象被反序列化。但是,没有什么能阻止构思不周的 OQL 查询 导致反序列化,所以要小心。Region.get(key)Functionspring-doc.cn

数据序列化 + PDX + Java 序列化

Apache Geode 可以同时支持所有 3 种序列化格式。spring-doc.cn

例如,您的应用程序域模型可能包含实现接口 并且您可能正在使用 Data Serialization 框架和 PDX 的组合。java.io.Serialiablespring-doc.cn

虽然可以将 Java 序列化Data Serialization 和 PDX 一起使用,但通常更可取 ,建议使用 1 个序列化策略。
Java 序列化不同,数据序列化和 PDX 序列化不处理对象图周期。

有关 Apache Geode 序列化机制的更多背景信息,请参阅此处spring-doc.cn

3.6.2. 使用 Spring Session 进行序列化

以前,Spring Session for Apache Geode 仅支持 Apache Geode 数据序列化格式。主要的 这背后的动机是利用 Apache Geode 的 Delta Propagation 功能,因为 Session 的 state 可以是任意大的。spring-doc.cn

但是,从 Spring Session for Apache Geode 2.0 开始,PDX 也受支持,现在是新的默认序列化 选择。在 Spring Session for Apache Geode 2.0 中,默认值更改为 PDX,主要是因为 PDX 是最 用户广泛使用和请求的格式。spring-doc.cn

PDX 无疑是最灵活的格式,以至于您甚至不需要 Spring Session for Apache Geode 或其对集群中服务器的 Classpath 的任何传递依赖项,以使用 Spring Session Apache Geode 的 Apache。事实上,使用 PDX,您甚至不需要将应用程序域对象类型存储在 服务器的 Classpath 上的 (HTTP) Session。spring-doc.cn

实质上,在使用 PDX 序列化时,Apache Geode 不需要存在关联的 Java 类型 在服务器的 Classpath 上。只要集群中的服务器上没有发生反序列化,您就是安全的。spring-doc.cn

该注解引入了一个新属性,即用户 可用于配置在 Spring 容器中声明和注册的 bean 的名称,该 bean 实现了所需的 序列化策略。Spring Session for Apache Geode 使用序列化策略进行序列化 Session 状态。@EnableGemFireHttpSessionsessionSerializerBeanNamespring-doc.cn

Spring Session for Apache Geode 提供 2 种开箱即用的序列化策略:1 种用于 PDX,1 种用于数据序列化。它会自动在 Spring 容器中注册两个序列化策略 bean。 但是,这些策略中只有 1 种在运行时实际使用,即 PDX!spring-doc.cn

在实现数据序列化和 PDX 的 Spring 容器中注册的 2 个 bean 分别命名为 和 。默认情况下,属性 设置为 ,就像用户注释了他/她的 Spring Boot、启用了 Spring Session 的应用程序一样 configuration 类替换为:SessionDataSerializerSessionPdxSerializersessionSerializerBeanNameSessionPdxSerializerspring-doc.cn

@SpringBootApplication
@EnableGemFireHttpSession(sessionSerializerBeanName = "SessionPdxSerializer")
class MySpringSessionApplication {  }

通过将属性设置为 ,将序列化策略更改为 Data Serialization 是一件简单的事情,如下所示:sessionSerializerBeanNameSessionDataSerializerspring-doc.cn

@SpringBootApplication
@EnableGemFireHttpSession(sessionSerializerBeanName = "SessionDataSerializer")
class MySpringSessionApplication {  }

由于这两个值非常常见,因此 Spring Session for Apache Geode 为类中的每个值提供常量: 和 。因此,您可以显式配置 PDX, 如下:GemFireHttpSessionConfigurationGemFireHttpSessionConfiguration.SESSION_PDX_SERIALIZER_BEAN_NAMEGemFireHttpSessionConfiguration.SESSION_DATA_SERIALIZER_BEAN_NAMEspring-doc.cn

import org.springframework.session.data.geode.config.annotation.web.http.GemFireHttpSessionConfiguration;

@SpringBootApplication
@EnableGemFireHttpSession(sessionSerializerBeanName = GemFireHttpSessionConfiguration.SESSION_PDX_SERIALIZER_BEAN_NAME)
class MySpringSessionApplication {  }

使用 1 个属性和 2 个开箱即用的 bean 定义,您可以指定所需的序列化框架 与由 Apache Geode 支持的支持 Spring Session 的 Spring Boot 应用程序一起使用。spring-doc.cn

3.6.3. Spring Session for Apache Geode 序列化框架

为了抽象出 Apache Geode 的数据序列化和 PDX 序列化框架的细节, Spring Session for Apache Geode 提供了自己的序列化框架(门面),将 Apache Geode 的 序列化框架。spring-doc.cn

序列化 API 存在于包下。主要 此 API 中的接口是 .org.springframework.session.data.gemfire.serializationorg.springframework.session.data.gemfire.serialization.SessionSerializerspring-doc.cn

接口定义为:spring-doc.cn

Spring Session 接口SessionSerializer
interface SessionSerializer<T, IN, OUT> {

  void serialize(T session, OUT out);

  T deserialize(IN in);

  boolean canSerialize(Class<?> type);

  boolean canSerialize(Object obj) {
    // calls Object.getClass() in a null-safe way and then calls and returns canSerialize(:Class)
  }
}

基本上,该接口允许你序列化和反序列化 Spring 对象。Sessionspring-doc.cn

这些类型的 and 类型参数和相应的方法参数提供对对象的引用 负责将 写入字节流或从字节流中读取。实际的 参数将特定于类型,具体取决于配置的基础 Apache Geode 序列化策略。INOUTSessionSessionspring-doc.cn

例如,当使用 Apache Geode 的 PDX 序列化框架时,将分别是 和 的实例。配置 Apache Geode 的数据序列化框架后,则 和 将分别是 和 的实例。INOUTorg.apache.geode.pdx.PdxReaderorg.apache.geode.pdx.PdxWriterINOUTjava.io.DataInputjava.io.DataOutputspring-doc.cn

这些参数由框架自动提供给实现,并且作为 前面提到的,是基于配置的底层 Apache Geode 序列化策略。SessionSerializerspring-doc.cn

从本质上讲,尽管 Spring Session for Apache Geode 为 Apache Geode 的 序列化框架,在后台 Apache Geode 仍然需要这些序列化框架之一 用于将数据序列化到 Apache Geode 或从 Apache Geode 序列化数据。spring-doc.cn

那么 SessionSerializer 接口的真正用途是什么呢?spring-doc.cn

实际上,它允许用户自定义 Session 状态的哪些方面实际被序列化和存储 在 Apache Geode 中。应用程序开发人员可以提供他们自己的自定义的、特定于应用程序的实现,在 Spring 容器中将其注册为 Bean,然后将其配置为由 Spring Session 使用 用于序列化 Session 状态,如下所示:SessionSerializerspring-doc.cn

@EnableGemFireHttpSession(sessionSerializerBeanName = "MyCustomSessionSerializer")
class MySpringSessionDataGemFireApplication {

  @Bean("MyCustomSessionSerializer")
  SessionSerializer<Session, ?, ?> myCustomSessionSerializer() {
    // ...
  }
}
实现 SessionSerializer

Spring Session for Apache Geode 在用户想要实现适合 Apache Geode 的序列化框架之一的自定义时提供帮助。SessionSerializerspring-doc.cn

如果用户只是实现接口 直接扩展,而无需从 Spring Session for Apache Geode 提供的抽象基类之一扩展,相关的 添加到 Apache Geode 的 Serialization 框架之一,则 Spring Session for Apache Geode 会将用户的 自定义实现,并将其作为 .org.springframework.session.data.gemfire.serialization.SessionSerializerSessionSerializerorg.springframework.session.data.gemfire.serialization.pdx.support.PdxSerializerSessionSerializerAdapterorg.apache.geode.pdx.PdxSerializerspring-doc.cn

Spring Session for Apache Geode 小心翼翼地避免STOMP踏用户 可能已经通过其他方式向 Apache Geode 注册。事实上,有几种不同的,只要 存在 Apache Geode 接口的实现:PdxSerializerorg.apache.geode.pdx.PdxSerializerspring-doc.cn

这是通过获取缓存上任何当前注册的实例并对其进行组合来实现的 包装用户的自定义应用程序实现并在 Apache Geode 缓存上重新注册此 “复合”。“复合”实现由 Spring Session for Apache Geode 的类提供 当实体作为 PDX 存储在 Apache Geode 中时。PdxSerializerPdxSerializerSessionSerializerAdapterSessionSerializerPdxSerializerPdxSerializerorg.springframework.session.data.gemfire.pdx.support.ComposablePdxSerializerspring-doc.cn

如果当前没有其他 API 注册到 Apache Geode 缓存中,则适配器 只是注册了。PdxSerializerspring-doc.cn

当然,您可以通过执行以下 1 项操作来强制将基础 Apache Geode 序列化策略与自定义实现一起使用:SessionSerializerspring-doc.cn

  1. 自定义实现可以实现 Apache Geode 的接口,或者为方便起见,扩展 Spring Session for Apache Geode 的类 Spring Session for Apache Geode 会将自定义注册为 a 到 Apache Geode。SessionSerializerorg.apache.geode.pdx.PdxSerializerorg.springframework.session.data.gemfire.serialization.pdx.AbstractPdxSerializableSessionSerializerSessionSerializerPdxSerializerspring-doc.cn

  2. 自定义实现可以扩展 Apache Geode 的类,或者为方便起见,扩展 Spring Session for Apache Geode 的类 Spring Session for Apache Geode 会将自定义注册为 a 到 Apache Geode。SessionSerializerorg.apache.geode.DataSerializerorg.springframework.session.data.gemfire.serialization.data.AbstractDataSerializableSessionSerializerSessionSerializerDataSerializerspring-doc.cn

  3. 最后,用户可以像以前一样创建自定义实现,而无需指定哪个 Apache Geode 序列化框架,因为自定义实现未实现 任何 Apache Geode 序列化接口或从 Spring Session for Apache Geode 提供的任何 抽象基类,并且仍然在 Apache Geode 中将其注册为 a,方法是声明 在 Spring 容器中的附加 Spring Session for Apache Geode bean 类型为 ,如下所示...SessionSerializerSessionSeriaizerDataSerializerorg.springframework.session.data.gemfire.serialization.data.support.DataSerializerSessionSerializerAdapterspring-doc.cn

在 Apache Geode 中强制将自定义 SessionSerializer 注册为 DataSerializer
@EnableGemFireHttpSession(sessionSerializerBeanName = "customSessionSerializer")
class Application {

	@Bean
	DataSerializerSessionSerializerAdapter dataSerializerSessionSerializer() {
		return new DataSerializerSessionSerializerAdapter();
	}

	@Bean
	SessionSerializer<Session, ?, ?> customSessionSerializer() {
		// ...
	}
}

只是因为 Spring 容器中注册为 bean 的存在, 任何中性自定义实现都将被视为 Apache Geode 中的一个。DataSerializerSessionSerializerAdapterSessionSerializerDataSerializerspring-doc.cn

对数据序列化的额外支持
如果您正在配置和引导 Apache Geode 服务器,请随时跳过本节 在您的集群中使用 Spring (Boot),因为通常以下信息将不适用。答案是肯定的 这完全取决于你声明的依赖项和 Spring 配置。但是,如果您使用 Gfsh 启动集群中的服务器,那么请务必继续阅读。
背景

使用 Apache Geode 的 DataSerialization 框架时,尤其是在序列化 (HTTP) 会话时从客户端 状态添加到集群中的服务器,则必须注意在集群中配置 Apache Geode 服务器 替换为适当的依赖项。如前一节所述,在利用增量时尤其如此 在 Data Serialization 上。spring-doc.cn

当使用 DataSerialization 框架作为序列化策略来序列化 (HTTP) 会话状态时 你的 Web 应用程序客户端连接到服务器,那么服务器必须正确地配置 Spring Session ,用于表示 (HTTP) 会话及其内容的 Apache Geode 类类型。这意味着包括 服务器 Classpath 上的 Spring JAR。spring-doc.cn

此外,使用 DataSerialization 可能还需要包含包含应用程序域的 JAR 类,这些类由 Web 应用程序使用,并作为 Session Attribute 值放入 (HTTP) Session 中, 特别是在以下情况下:spring-doc.cn

  1. 您的类型实现接口。org.apache.geode.DataSerializablespring-doc.cn

  2. 您的类型实现接口。org.apache.geode.Deltaspring-doc.cn

  3. 您已注册一个 用于标识和序列化类型。org.apache.geode.DataSerializerspring-doc.cn

  4. 您的类型实现接口。java.io.Serializablespring-doc.cn

当然,您必须确保放置在 (HTTP) Session 中的应用程序域对象类型在某些 形式或其他形式。但是,并非严格要求您使用 DataSerialization,也不必如此 在以下情况下,需要将应用程序域对象类型放在 servers 类路径上:spring-doc.cn

  1. 您的类型实现接口。org.apache.geode.pdx.PdxSerializablespring-doc.cn

  2. 或者,您已经注册了一个正确标识和序列化 您的应用程序域对象类型。org.apache.geode.pdx.PdxSerializerspring-doc.cn

Apache Geode 在确定要使用的序列化策略时,将应用以下优先顺序 要序列化对象图:spring-doc.cn

  1. 首先,对象和/或任何已注册的标识要序列化的对象。DataSerializableDataSerializersspring-doc.cn

  2. 然后 objects 和/或任何已注册的标识要序列化的对象。PdxSerializablePdxSerializerspring-doc.cn

  3. 最后,所有类型。java.io.Serializablespring-doc.cn

这也意味着,如果特定的应用程序域对象类型(例如 )实现 , 但是,已向 Apache Geode 注册了一个 (custom) 以标识相同的应用程序 domain 对象类型(即 ),则 Apache Geode 将使用 PDX 来序列化 “A” 而不是 Java 序列化, 在这种情况下。Ajava.io.SerializablePdxSerializerAspring-doc.cn

这特别有用,因为您可以使用 DataSerialization 来序列化 (HTTP) Session 对象,利用 增量和 DataSerialization 的所有强大功能,但随后使用 PDX 序列化应用程序域对象 类型,这大大简化了所涉及的配置和/或工作。spring-doc.cn

现在我们已经大致了解了为什么存在这种支持,您如何启用它?spring-doc.cn

配置

首先,创建一个 Apache Geode ,如下所示:cache.xmlspring-doc.cn

Apache Geode 配置cache.xml
<?xml version="1.0" encoding="UTF-8"?>
<cache xmlns="http://geode.apache.org/schema/cache"
	   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	   xsi:schemaLocation="http://geode.apache.org/schema/cache https://geode.apache.org/schema/cache/cache-1.0.xsd"
	   version="1.0">

  <initializer>
    <class-name>
      org.springframework.session.data.gemfire.serialization.data.support.DataSerializableSessionSerializerInitializer
    </class-name>
  </initializer>

</cache>

然后,在 *Gfsh* 中使用以下命令启动您的服务器:spring-doc.cn

使用 Gfsh 启动 Server
gfsh> start server --name=InitializedServer --cache-xml-file=/path/to/cache.xml --classpath=...

使用适当的依赖项配置 Apache Geode 服务器是棘手的部分, 但一般来说,以下内容应该有效:classpathspring-doc.cn

CLASSPATH 配置
gfsh> set variable --name=REPO_HOME --value=${USER_HOME}/.m2/repository

gfsh> start server ... --classpath=\
${REPO_HOME}/org/springframework/spring-core/{spring-version}/spring-core-{spring-version}.jar\
:${REPO_HOME}/org/springframework/spring-aop/{spring-version}/spring-aop-{spring-version}.jar\
:${REPO_HOME}/org/springframework/spring-beans/{spring-version}/spring-beans-{spring-version}.jar\
:${REPO_HOME}/org/springframework/spring-context/{spring-version}/spring-context-{spring-version}.jar\
:${REPO_HOME}/org/springframework/spring-context-support/{spring-version}/spring-context-support-{spring-version}.jar\
:${REPO_HOME}/org/springframework/spring-expression/{spring-version}/spring-expression-{spring-version}.jar\
:${REPO_HOME}/org/springframework/spring-jcl/{spring-version}/spring-jcl-{spring-version}.jar\
:${REPO_HOME}/org/springframework/spring-tx/{spring-version}/spring-tx-{spring-version}.jar\
:${REPO_HOME}/org/springframework/data/spring-data-commons/{spring-data-commons-version}/spring-data-commons-{spring-data-commons-version}.jar\
:${REPO_HOME}/org/springframework/data/spring-data-geode/{spring-data-geode-version}/spring-data-geode-{spring-data-geode-version}.jar\
:${REPO_HOME}/org/springframework/session/spring-session-core/{spring-session-core-version}/spring-session-core-{spring-session-core-version}.jar\
:${REPO_HOME}/org/springframework/session/spring-session-data-geode/{spring-session-data-geode-version}/spring-session-data-geode-{spring-session-data-geode-version}.jar\
:${REPO_HOME}/org/slf4j/slf4j-api/1.7.25/slf4j-api-1.7.25.jar

请记住,您可能还需要将应用程序域对象 JAR 文件添加到服务器 Classpath 中。spring-doc.cn

要全面了解其工作原理,请参阅示例spring-doc.cn

自定义变化检测

默认情况下,每当 Session 被修改(例如,更新到当前时间)时,Session 被 Spring Session for Apache Geode (SSDG) 视为脏的。在使用 Apache Geode 数据序列化框架时,利用 Apache Geode 的增量传播功能也非常有用和有价值。lastAccessedTimespring-doc.cn

使用数据序列化时,SSDG 还使用增量传播仅发送对 Session 状态的更改 客户端和服务器。这包括可能已添加、删除或更新的任何 Session 属性。spring-doc.cn

默认情况下,只要调用了 session,Session 属性就被认为是 “dirty” ,并将在 Client 端和 Server 之间的 delta 中发送。即使您的应用程序域对象 未更改。Session.setAttribute(name, value)spring-doc.cn

通常,除非您的对象已更改,否则永远不会有理由调用然而 如果发生这种情况,并且您的对象相对较大(具有复杂的对象层次结构),则可能需要 请考虑以下任一内容:Session.setAttribute(..)spring-doc.cn

  1. 在应用程序域对象中实现 Delta 接口 模型虽然有用,但侵入性很强,或者......spring-doc.cn

  2. 提供 SSDG 策略接口的自定义实现。org.springframework.session.data.gemfire.support.IsDirtyPredicatespring-doc.cn

SSDG 提供了 5 种开箱即用的策略接口实现:IsDirtyPredicatespring-doc.cn

表 5. 实现IsDirtyPredicate
描述 违约

IsDirtyPredicate.ALWAYS_DIRTYspring-doc.cn

新的 Session 属性值始终被视为脏。spring-doc.cn

IsDirtyPredicate.NEVER_DIRTYspring-doc.cn

新的 Session 属性值永远不会被视为脏。spring-doc.cn

DeltaAwareDirtyPredicatespring-doc.cn

当旧值和新值 是不同的,如果新值的 type 未实现或新值的方法返回 trueDeltaDelta.hasDelta()spring-doc.cn

是的spring-doc.cn

EqualsDirtyPredicatespring-doc.cn

如果旧值不等于 由 method 确定的新值。Object.equals(:Object)spring-doc.cn

IdentityEqualsPredicatespring-doc.cn

如果旧值与 使用标识等于运算符的新值(即 )。oldValue != newValuespring-doc.cn

如上表所示,这是 SSDG 使用的默认实现。 这会自动考虑实现 Apache Geode 界面。但是,即使您的应用程序 domain 对象不实现接口。SSDG 会将您的应用程序域对象视为脏 每当调用时,如果新值与旧值不同,则 或者新值不实现接口。DeltaAwareDirtyPredicateDeltaAwareDirtyPredicateDeltaDeltaAwareDirtyPredicateDeltaSession.setAttribute(name, newValue)Deltaspring-doc.cn

您只需在 Spring 容器中声明一个 bean 即可更改 SSDG 的脏实现、确定策略 接口类型中:IsDirtyPredicatespring-doc.cn

覆盖 SSDG 的默认策略IsDirtyPredicate
@EnableGemFireHttpSession
class ApplicationConfiguration {

  @Bean
  IsDirtyPredicate equalsDirtyPredicate() {
    return EqualsDirtyPredicate.INSTANCE;
  }
}
组成

该接口还提供了 and 方法 在一个组合中组合 2 个或多个实现,以便组织复杂的逻辑和规则 用于确定应用程序域对象是否脏。IsDirtyPredicateandThen(:IsDirtyPredicate)orThen(:IsDirtyPredicate)IsDirtyPredicatespring-doc.cn

例如,您可以同时使用 OR 运算符组合两者:EqualsDirtyPredicateDeltaAwareDirtyPredicatespring-doc.cn

使用逻辑 OR 运算符进行撰写EqualsDirtyPredicateDeltaAwareDirtyPredicate
@EnableGemFireHttpSession
class ApplicationConfiguration {

  @Bean
  IsDirtyPredicate equalsOrThenDeltaDirtyPredicate() {

    return EqualsDirtyPredicate.INSTANCE
      .orThen(DeltaAwareDirtyPredicate.INSTANCE);
  }
}

您甚至可以根据特定的应用程序域对象类型实现自己的自定义:IsDirtyPredicatesspring-doc.cn

特定于应用程序域对象类型的实现IsDirtyPredicate
class CustomerDirtyPredicate implements IsDirtyPredicate {

  public boolean isDirty(Object oldCustomer, Object newCustomer) {

      if (newCustomer instanceof Customer) {
        // custom logic to determine if a new Customer is dirty
      }

      return true;
  }
}

class AccountDirtyPredicate implements IsDirtyPredicate {

  public boolean isDirty(Object oldAccount, Object newAccount) {

      if (newAccount instanceof Account) {
        // custom logic to determine if a new Account is dirty
      }

      return true;
  }
}

然后与 the 和 default 谓词组合用于回退,如下所示:CustomerDirtyPredicateAccountDirtyPredicatespring-doc.cn

组合和配置特定于类型IsDirtyPredicates
@EnableGemFireHttpSession
class ApplicationConfiguration {

  @Bean
  IsDirtyPredicate typeSpecificDirtyPredicate() {

    return new CustomerDirtyPredicate()
      .andThen(new AccountDirtyPredicate())
      .andThen(IsDirtyPredicate.ALWAYS_DIRTY);
  }
}

组合和可能性是无穷无尽的。spring-doc.cn

实施自定义策略时要小心。如果您错误地确定 application domain 对象不是脏的,那么它不会在 Session delta 中发送 从客户端到服务器。IsDirtyPredicate
更改 Session 表示

在内部,Spring Session for Apache Geode 维护 (HTTP) Session 和 Session 的 属性。每种表示形式都基于是否支持 Apache Geode“增量”。spring-doc.cn

由于前面讨论的原因,在使用数据序列化时,只有 Spring Session for Apache Geode 才会启用 Apache Geode 增量传播spring-doc.cn

实际上,该策略是:spring-doc.cn

  1. 如果配置了 Apache Geode 数据序列化,则支持 Deltas 并使用 and 表示形式。DeltaCapableGemFireSessionDeltaCapableGemFireSessionAttributesspring-doc.cn

  2. 如果配置了 Apache Geode PDX 序列化,则将禁用增量传播 和 和 表示形式。GemFireSessionGemFireSessionAttributesspring-doc.cn

可以覆盖 Spring Session for Apache Geode 和用户使用的这些内部表示 来提供自己的 Session 相关类型。唯一严格的要求是 Session 实现 必须实现核心 Spring Session 接口。org.springframework.session.Sessionspring-doc.cn

举个例子,假设你想定义自己的 Session 实现。spring-doc.cn

首先,定义类型。也许您的自定义类型甚至封装并处理了 Session 属性,而不必定义单独的类型。SessionSessionspring-doc.cn

用户定义的 Session 接口实现
class MySession implements org.springframework.session.Session {
  // ...
}

然后,您需要扩展类 并覆盖该方法以创建自定义实现类的实例。org.springframework.session.data.gemfire.GemFireOperationsSessionRepositorycreateSession()Sessionspring-doc.cn

自定义 SessionRepository 实现创建并返回自定义 Session 类型的实例
class MySessionRepository extends GemFireOperationsSessionRepository {

  @Override
  public Session createSession() {
    return new MySession();
  }
}

如果您提供自己的自定义实现,并且 Apache Geode PDX 序列化为 configured,然后您完成了。SessionSerializerspring-doc.cn

但是,如果您配置了 Apache Geode 数据序列化,则必须另外提供自定义 实现接口,并让它直接扩展 Apache Geode 的类,或者扩展 Spring Session for Apache Geode 的类 并覆盖该方法。SessionSerializerorg.apache.geode.DataSerializerorg.springframework.session.data.gemfire.serialization.data.AbstractDataSerializableSessionSerializergetSupportedClasses():Class<?>[]spring-doc.cn

例如:spring-doc.cn

自定义 Session 类型的自定义 SessionSerializer
class MySessionSerializer extends AbstractDataSerializableSessionSerializer {

  @Override
  public Class<?>[] getSupportedClasses() {
    return new Class[] { MySession.class };
  }
}

不幸的是,无法返回通用的 Spring Session 接口类型。如果可以,那么我们可以避免显式需要覆盖 自定义实现。但是,Apache Geode 的数据序列化框架只能匹配 在确切的类类型上,因为它错误地在内部存储并按名称引用类类型,然后 要求用户重写并实现该方法。getSupportedClasses()org.springframework.session.SessiongetSupportedClasses()DataSerializergetSupportedClasses()spring-doc.cn

3.7. HttpSession 集成的工作原理

幸运的是,和 (用于 获取 ) 是接口。这意味着我们可以为每个 API 提供自己的实现。javax.servlet.http.HttpSessionjavax.servlet.http.HttpServletRequestHttpSessionspring-doc.cn

本节介绍 Spring Session 如何提供与 的透明集成。 其目的是让用户了解后台发生的事情。此功能已实现 和 integrated 的,因此您无需自己实现此 logic。javax.servlet.http.HttpSession

首先,我们创建一个自定义,该自定义返回 .它看起来像下面这样:javax.servlet.http.HttpServletRequestjavax.servlet.http.HttpSessionspring-doc.cn

public class SessionRepositoryRequestWrapper extends HttpServletRequestWrapper {

	public SessionRepositoryRequestWrapper(HttpServletRequest original) {
		super(original);
	}

	public HttpSession getSession() {
		return getSession(true);
	}

	public HttpSession getSession(boolean createNew) {
		// create an HttpSession implementation from Spring Session
	}

	// ... other methods delegate to the original HttpServletRequest ...
}

任何返回 an 的方法都将被覆盖。所有其他方法都由原始实现实现,并简单地委托给原始实现。javax.servlet.http.HttpSessionjavax.servlet.http.HttpServletRequestWrapperjavax.servlet.http.HttpServletRequestspring-doc.cn

我们使用名为 .伪代码可以在下面找到:javax.servlet.http.HttpServletRequestFilterSessionRepositoryFilterspring-doc.cn

public class SessionRepositoryFilter implements Filter {

	public doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {

		HttpServletRequest httpRequest = (HttpServletRequest) request;

		SessionRepositoryRequestWrapper customRequest = new SessionRepositoryRequestWrapper(httpRequest);

		chain.doFilter(customRequest, response, chain);
	}

	// ...
}

通过将自定义实现传入 我们确保 在 our 之后调用的任何内容都使用 custom 实现。javax.servlet.http.HttpServletRequestFilterChainFilterjavax.servlet.http.HttpSessionspring-doc.cn

这凸显了为什么必须将 Spring Session 放在任何事情之前很重要 它与 .SessionRepositoryFilterjavax.servlet.http.HttpSessionspring-doc.cn

3.8. HttpSession监听器

Spring Session 通过翻译和声明 into 来支持。HttpSessionListenerSessionCreatedEventSessionDestroyedEventHttpSessionEventSessionEventHttpSessionListenerAdapterspring-doc.cn

要使用此支持,您需要:spring-doc.cn

  • 确保您的实施支持并配置为触发 and'SessionDestroyedEvent'。SessionRepositorySessionCreatedEventspring-doc.cn

  • 配置为 Spring Bean。SessionEventHttpSessionListenerAdapterspring-doc.cn

  • 将 every 注入到HttpSessionListenerSessionEventHttpSessionListenerAdapterspring-doc.cn

如果您将 HttpSession 中记录的配置支持与 Apache Geode 结合使用, 然后,您需要做的就是将 every 注册为 bean。HttpSessionListenerspring-doc.cn

例如,假设您希望支持 Spring Security 的并发控制,并且需要使用 , 然后,您可以简单地添加为 Bean。HttpSessionEventPublisherHttpSessionEventPublisherspring-doc.cn

3.9. 会话

A 是支持过期的简化键/值对。SessionMapspring-doc.cn

3.10. SessionRepository

A 负责创建、保存和访问实例和状态。SessionRepositorySessionspring-doc.cn

如果可能,开发人员不应直接与 或 .相反,开发人员 应该更喜欢与 和 和 集成进行交互和间接交互。SessionRepositorySessionSessionRepositorySessionjavax.servlet.http.HttpSessionWebSocketWebSessionspring-doc.cn

3.11. FindByIndexNameSessionRepository

Spring Session 使用 的最基本 API 是 .API 故意非常简单 这样就很容易提供具有基本功能的其他 implementations。SessionSessionRepositoryspring-doc.cn

某些 implementations 可能会选择同时实现。 例如,Spring Session 的 Apache Geode 支持实现了 .SessionRepositoryFindByIndexNameSessionRepositoryFindByIndexNameSessionRepositoryspring-doc.cn

这添加了一个方法来查找特定用户的所有会话。 这是通过确保带有 name 的 session 属性填充用户名来完成的。开发人员有责任确保填充该属性,因为 Spring Session 不知道正在使用的身份验证机制。FindByIndexNameSessionRepositoryFindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAMEspring-doc.cn

的一些 implementation will 提供钩子来自动索引其他 session 属性。 例如,许多实现将自动确保当前的 Spring Security 用户名使用 索引名称 .FindByIndexNameSessionRepositoryFindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAMEspring-doc.cn

3.12. 启用 SpringHttpSession

可以将注释添加到任何类中,以将 Bean 公开为名为“springSessionRepositoryFilter”的 Spring 容器中的 Bean。@EnableSpringHttpSession@ConfigurationSessionRepositoryFilterspring-doc.cn

为了利用 Comments,必须提供单个 bean。SessionRepositoryspring-doc.cn

3.13. 启用 GemFireHttpSession

可以将注释添加到任何类中,以代替注释,以在 Spring 容器中将 bean 公开为名为 “springSessionRepositoryFilter”,并将 Apache Geode 定位为管理状态的提供程序。@EnableGemFireHttpSession@Configuration@EnableSpringHttpSessionSessionRepositoryFilterjavax.servlet.http.HttpSessionspring-doc.cn

使用 annotation 时,额外的配置是开箱即用的,这也 提供了名为 的接口的 Apache Geode 特定实现。@EnableGemFireHttpSessionSessionRepositoryGemFireOperationsSessionRepositoryspring-doc.cn

3.14. GemFireOperationsSessionRepository

GemFireOperationsSessionRepository是使用 Spring Session 实现的 适用于 Apache Geode 的 s_ .SessionRepositoryGemFireOperationsSessionRepositoryspring-doc.cn

在 Web 环境中,此存储库与 .SessionRepositoryFilterspring-doc.cn

此实现支持 ,并通过 .SessionCreatedEventsSessionDeletedEventsSessionDestroyedEventsSessionEventHttpSessionListenerAdapterspring-doc.cn

3.14.1. 在 Apache Geode 中使用索引

虽然有关正确定义对 Apache Geode 性能有积极影响的索引的最佳实践 超出了本文档的范围,重要的是要认识到 Spring Session for Apache Geode 会创建 并使用 Indexes 高效地查询和查找 Sessions。spring-doc.cn

Spring Session for Apache Geode 在主体名称上创建 1 个哈希类型的索引。有两个 用于查找 Principal Name 的不同内置策略。第一个策略是 Session 的值 属性将被索引到相同的 索引名称。FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAMEspring-doc.cn

例如:spring-doc.cn

String indexName = FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME;

session.setAttribute(indexName, username);
Map<String, Session> idToSessions =
	this.sessionRepository.findByIndexNameAndIndexValue(indexName, username);

3.14.2. 在 Apache Geode 和 Spring Security 中使用索引

或者,Spring Session for Apache Geode 会将 Spring Security 的当前映射到 索引 .Authentication#getName()FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAMEspring-doc.cn

例如,如果您使用的是 Spring Security,则可以使用以下方法查找当前用户的会话:spring-doc.cn

SecurityContext securityContext = SecurityContextHolder.getContext();
Authentication authentication = securityContext.getAuthentication();
String indexName = FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME;

Map<String, Session> idToSessions =
	this.sessionRepository.findByIndexNameAndIndexValue(indexName, authentication.getName());

3.14.3. 在 Apache Geode 中使用自定义索引

这使开发人员能够使用编程方式查询和查找所有会话 有效地使用给定的主体名称。GemFireOperationsSessionRepositoryspring-doc.cn

此外,Spring Session for Apache Geode 将在实现 Session 的 Map 类型属性(即在任何任意 Session 属性上),当开发人员标识 1 个或多个 命名的 Session 属性,这些属性应由 Apache Geode 编制索引。attributesspring-doc.cn

可以使用 Comments 上的属性指定要索引的 Sessions 属性。当开发人员希望启用 Spring Session 对 backed by 的支持时,将这个注解添加到他们的 Spring 应用程序类中 Apache Geode 的 Apache。indexableSessionAttributes@EnableGemFireHttpSession@ConfigurationHttpSessionspring-doc.cn

String indexName = "name1";

session.setAttribute(indexName, indexValue);
Map<String, Session> idToSessions =
	this.sessionRepository.findByIndexNameAndIndexValue(indexName, indexValue);
只有在 annotation 的属性中标识的 Session 属性名称才会定义 Index。不会为所有其他 Session 属性编制索引。@EnableGemFireHttpSessionindexableSessionAttributes

但是,有一个问题。存储在可索引 Session 属性中的任何值都必须实现该接口。如果这些对象值未实现 ,则 Apache Geode 将在启动时引发错误,当为具有持久 Session 数据的区域定义 Index 时,或者尝试 在运行时进行,以便为可索引的 Session 属性分配一个不是的值,并保存 Session 到 Apache Geode。java.lang.Comparable<T>ComparableComparablespring-doc.cn

任何未编制索引的 Session 属性都可以存储非 - 值。Comparable

要了解有关 Apache Geode 基于范围的索引的更多信息,请参阅在映射字段上创建索引spring-doc.cn

要了解有关 Apache Geode 索引的一般信息,请参阅使用索引spring-doc.cn