3. HttpSession 集成
Spring Session 提供与 .这意味着开发人员
可以用 Spring Session 支持的实现替换该实现。javax.servlet.http.HttpSession
HttpSession
Spring Session 支持插入多个不同的数据存储提供程序(例如,如 Apache Geode)
为了管理国家。HttpSession
3.1. 为什么选择Spring Session和HttpSession?
我们已经提到 Spring Session 提供了与 的透明集成,但是有什么好处
我们能摆脱这一切吗?HttpSession
-
HttpSession - 使 能够被集群化(即复制的 以实现高可用性),而无需绑定到特定于应用程序容器的解决方案。
HttpSession
-
REST API - 允许在协议标头中提供会话 ID,以便与 RESTful API 一起使用。
-
WebSocket - 提供在接收 WebSocket 消息时保持活动状态的能力。
HttpSession
-
WebSession - 允许以应用程序容器中立的方式替换 Spring WebFlux。
WebSession
3.2. 使用 Apache Geode 进行 HttpSession 管理
当 Apache Geode 与 Spring Session 一起使用时,Web 应用程序的 Web 应用程序可以替换为由 Apache Geode 管理的集群实现
并使用 Spring Session 的 API 方便地访问。javax.servlet.http.HttpSession
使用 Apache Geode 管理会话状态的两种最常见拓扑包括:
此外,Apache Geode 还支持使用 WAN 拓扑进行站点到站点复制。 配置和使用 Apache Geode 的 WAN 功能的能力独立于 Spring Session、 并且超出了本文档的范围。
有关使用 Spring Data for Apache Geode 配置 Apache Geode WAN 功能的更多详细信息 可以在这里找到。
3.2.1. Apache Geode 客户端-服务器
客户端-服务器拓扑可能是 在 Spring Session 中使用 Apache Geode 作为提供程序时,用户最常见的配置选择,因为 与应用程序相比,Apache Geode 服务器具有明显不同且独特的 JVM 堆要求。 使用 Client-Server 拓扑使应用程序能够独立管理(例如复制)应用程序状态 从其他应用程序进程。
在 Client-Server 拓扑中,使用 Spring Session 的应用程序将打开与远程集群的 1 个或多个连接
的 Apache Geode 服务器,这些服务器将管理对所有状态的访问。HttpSession
您可以使用以下任一方式配置客户端-服务器拓扑:
Apache Geode Client-Server 基于 Java 的配置
本节介绍如何配置 Apache Geode 的客户端-服务器拓扑以管理状态
使用基于 Java 的配置。HttpSession
带有 Apache Geode(客户端-服务器)的 HttpSession 提供了一个工作示例,演示如何
将 Spring Session 与 Apache Geode 集成,以使用 Java 配置管理状态。您可以阅读
通过下面的基本集成步骤,但我们鼓励您按照详细的 'HttpSession' 进行操作
与 Apache Geode (客户端-服务器) 指南集成时。HttpSession |
Spring Java 配置
添加所需的依赖项和存储库声明后,我们可以创建 Spring 配置。
Spring 配置负责创建一个 Servlet,该 Servlet 替换为 Spring Session 和 Apache Geode 支持的实现。Filter
HttpSession
客户端配置
添加以下 Spring 配置:
@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 @ClientCacheApplication Pool readTimeout |
2 | @EnableGemFireHttpSession 创建一个名为 的 Spring Bean,该 Bean 实现 .过滤器将 替换为 Spring Session 提供的实现
并由 Apache Geode 提供支持。此外,该配置还将创建必要的客户端(默认情况下,“ClusteredSpringSessions”,这是一个)按名称对应于同一服务器端。所有会话状态都通过数据访问操作从客户端发送到服务器。
客户端使用 “DEFAULT” 。springSessionRepositoryFilter javax.servlet.Filter HttpSession Region PROXY Region Region Region Region Pool |
3 | 然后,我们等待确保 Apache Geode Server 已启动并运行,然后再继续。这才真正有用 用于自动化 (集成) 测试目的。 |
在典型的 Apache Geode 生产部署中,集群可能包括数百或数千个 的服务器(也称为数据节点)中,客户端更常见的是连接到 1 个或多个正在运行的 Apache Geode 定位器 在同一个集群中。Locator 将有关集群中可用服务器的元数据传递给客户端,单个 server load 以及哪些服务器具有感兴趣的客户端数据,这对于 Direct 尤为重要。 单跳数据访问和延迟敏感型应用程序。有关客户端/服务器部署的更多详细信息,请参阅 Apache Geode 用户指南。 |
有关配置 Spring Data Geode 的更多信息,请参阅参考指南。 |
该注解使开发人员能够配置 Spring Session 的某些方面
和 Apache Geode 开箱即用,使用以下属性:@EnableGemFireHttpSession
-
clientRegionShortcut
- 使用 ClientRegionShortcut 在客户端上指定 Apache Geode 数据管理策略(默认值为 )。此属性仅在配置 client 时使用。PROXY
Region
-
indexableSessionAttributes
- 按名称标识 Session 应为查询目的编制索引的属性。 只有 name 显式标识的 Session 属性才会被索引。 -
maxInactiveIntervalInSeconds
- 控制 HttpSession 空闲超时过期时间(默认为 30 分钟)。 -
poolName
- 用于将客户端连接到服务器集群的专用 Apache Geode 的名称。 仅当应用程序是高速缓存客户端时,才使用此属性。默认为 。Pool
gemfirePool
-
regionName
- 指定用于存储和管理状态的 Apache Geode 的名称 (默认为 “ClusteredSpringSessions”)。Region
HttpSession
-
serverRegionShortcut
- 使用 RegionShortcut 指定服务器上的 Apache Geode 数据管理策略(默认值为 )。此属性仅在配置 server 时使用 或者当采用 P2P 拓扑时。PARTITION
Regions
请务必记住,如果客户端是 或 ,则 Apache Geode 客户端名称必须与同名服务器匹配。客户端和服务器名称
如果用于存储会话状态的客户端是 ,则不需要匹配。但是,请记住
该会话状态不会传播到服务器,并且您将失去使用 Apache Geode 的所有好处
要在分布式
复制方式。Region Region Region PROXY CACHING_PROXY Region Region LOCAL |
服务器配置
到目前为止,我们只介绍了等式的一面。我们还需要一个 Apache Geode 服务器,以便我们的缓存客户端与之通信 并将会话状态发送到服务器进行管理。
在此示例中,我们将使用以下 Java 配置来配置和运行 Apache Geode 服务器:
@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 实例的创建
包含用于缓存客户端连接的。@CacheServerApplication CacheServer |
2 | (可选)然后,对类进行注释以创建必要的
服务器端(默认为 “ClusteredSpringSessions”)用于存储状态。此步骤为
可选,因为 Session 可以手动创建,可能使用外部方式。
使用方便快捷。GemFireServer @EnableGemFireHttpSession Region HttpSession Region @EnableGemFireHttpSession |
Apache Geode 客户端-服务器基于 XML 的配置
本节介绍如何配置 Apache Geode 的客户端-服务器拓扑以管理状态
使用基于 XML 的配置。HttpSession
使用 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 支持的实现。Servlet
Filter
javax.servlet.http.HttpSession
客户端配置
添加以下 Spring 配置:
<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”
如果未指定。Properties ClientCache |
2 | 我们必须创建一个 Apache Geode 的实例。我们使用 .ClientCache gemfireProperties |
3 | 然后,我们配置一个连接,以便与客户端/服务器拓扑中的 Apache Geode 服务器通信。
在我们的配置中,我们对超时、连接数等使用合理的设置。此外,我们的已配置为直接连接到服务器(使用嵌套元素)。Pool Pool gfe:server |
4 | 最后,注册一个 bean 以启用 Spring Session 功能。GemFireHttpSessionConfiguration |
在典型的 Apache Geode 生产部署中,集群可能包括数百或数千个 的服务器(也称为数据节点)中,客户端更常见的是连接到 1 个或多个正在运行的 Apache Geode 定位器 在同一个集群中。Locator 将有关集群中可用服务器的元数据传递给客户端,单个 server load 以及哪些服务器具有感兴趣的客户端数据,这对于 Direct 尤为重要。 单跳数据访问和延迟敏感型应用程序。有关客户端/服务器部署的更多详细信息,请参阅 Apache Geode 用户指南。 |
有关为 Apache Geode 配置 Spring Data 的更多信息,请参阅参考指南。 |
服务器配置
到目前为止,我们只介绍了等式的一面。我们还需要一个 Apache Geode 服务器,以便我们的缓存客户端与之通信 并将会话状态发送到服务器进行管理。
在此示例中,我们将使用以下 XML 配置来启动 Apache Geode 服务器:
<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”
如果未指定。Properties Cache |
2 | 我们必须配置 Apache Geode 对等实例。我们使用 Apache Geode 属性对其进行初始化。Cache |
3 | 接下来,我们为缓存客户端定义一个具有合理配置并供其使用的
应用程序连接到服务器并发送会话状态。CacheServer bind-address port |
4 | 最后,我们启用我们在客户端 XML 配置中声明的相同 Spring Session 功能
通过注册 的实例,但我们设置了会话过期超时
设置为 30 秒。我们稍后会解释这意味着什么。GemFireHttpSessionConfiguration |
Apache Geode Server 使用以下方法进行引导:
@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 提供的自定义实现。springSessionRepositoryFilter
javax.servlet.Filter
springSessionRepositoryFilter
javax.servlet.http.HttpSession
为了让我们发挥它的魔力,我们需要指示 Spring 加载
我们的配置文件。Filter
session-client.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配置文件。contextConfigLocation
最后,我们需要确保我们的 Servlet 容器(即 Tomcat)对每个请求都使用我们的容器。springSessionRepositoryFilter
以下代码片段为我们执行了最后一步:
<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 请求,
调用,它将 .springSessionRepositoryFilter
Filter
DelegatingFilterProxy
springSessionRepositoryFilter
3.2.2. Apache Geode 点对点 (P2P)
一种不太常见的方法是将 Spring Session 应用程序配置为 Apache Geode 集群中的对等成员 使用点对点 (P2P) 拓扑。 在此配置中,Spring Session 应用程序将是 Apache Geode 中的实际服务器(或数据节点) cluster 的 CLUSTER,而不仅仅是像以前那样只是一个缓存客户端。
这种方法的一个优点是应用程序接近应用程序的状态(即它的数据),
尤其是国家。但是,还有其他有效的方法可以实现类似的
依赖于数据的计算,例如使用 Apache Geode 的 Function Execution。
在以下情况下可以使用 Apache Geode 的任何其他功能
Apache Geode 在 Spring Session 中充当提供程序。HttpSession
P2P 拓扑结构对于测试目的以及更小、更专注和独立的应用程序非常有用。 例如微服务架构中的那些,并且肯定会改善您的应用程序的感知 延迟和吞吐量需求。
您可以使用以下任一方式配置点对点 (P2P) 拓扑:
Apache Geode 点对点 (P2P) 基于 Java 的配置
本节介绍如何配置 Apache Geode 的点对点 (P2P) 拓扑以管理状态
使用基于 Java 的配置。HttpSession
HttpSession 与 Apache Geode (P2P) 提供了一个工作示例,演示如何
将 Spring Session 与 Apache Geode 集成,以使用 Java 配置管理状态。您可以阅读
通过下面的基本集成步骤,但我们鼓励您按照详细的 'HttpSession' 进行操作
与 Apache Geode (P2P) 指南集成时。HttpSession |
Spring Java 配置
添加所需的依赖项和存储库声明后,我们可以创建 Spring 配置。
Spring 配置负责创建一个,该配置将 替换为 Spring Session 和 Apache Geode 支持的实现。Servlet
Filter
javax.servlet.http.HttpSession
添加以下 Spring 配置:
@PeerCacheApplication(name = "SpringSessionDataGeodeJavaConfigP2pSample", logLevel = "error") (1)
@EnableGemFireHttpSession(maxInactiveIntervalInSeconds = 30) (2)
public class Config {
}
1 | 首先,我们使用 annotation 来简化 peer cache 实例的创建。@PeerCacheApplication |
2 | 然后,对类进行 Comments 以创建用于存储状态的必要服务器端(默认情况下为“ClusteredSpringSessions”)。Config @EnableGemFireHttpSession Region HttpSession |
有关为 Apache Geode 配置 Spring Data 的更多信息,请参阅参考指南。 |
该注解使开发人员能够配置 Spring Session 的某些方面
和 Apache Geode 开箱即用,使用以下属性:@EnableGemFireHttpSession
-
clientRegionShortcut
- 使用 ClientRegionShortcut 在客户端上指定 Apache Geode 数据管理策略(默认值为 )。此属性仅在配置 client 时使用。PROXY
Region
-
indexableSessionAttributes
- 按名称标识 Session 应为查询目的编制索引的属性。 只有 name 显式标识的 Session 属性才会被索引。 -
maxInactiveIntervalInSeconds
- 控制 HttpSession 空闲超时过期时间(默认为 30 分钟)。 -
poolName
- 用于将客户端连接到服务器集群的专用 Apache Geode 的名称。 仅当应用程序是高速缓存客户端时,才使用此属性。默认为 。Pool
gemfirePool
-
regionName
- 指定用于存储和管理状态的 Apache Geode 的名称 (默认为 “ClusteredSpringSessions”)。Region
HttpSession
-
serverRegionShortcut
- 使用 RegionShortcut 指定服务器上的 Apache Geode 数据管理策略(默认值为 )。此属性仅在配置 server 时使用 或者当采用 P2P 拓扑时。PARTITION
Regions
Java Servlet 容器初始化
我们的<<[httpsession-spring-java-configuration-p2p,Spring Java Configuration>>创建了一个名为 的 Spring Bean,它实现了 .豆子
负责将 替换为由
Spring Session 和 Apache Geode。springSessionRepositoryFilter
javax.servlet.Filter
springSessionRepositoryFilter
javax.servlet.http.HttpSession
为了让我们发挥它的魔力, Spring 需要加载我们的 class。我们还需要确保我们的
Servlet 容器(即 Tomcat)在每个 HTTP 请求上都使用 our。Filter
Config
springSessionRepositoryFilter
幸运的是,Spring Session 提供了一个名为
步骤非常简单。AbstractHttpSessionApplicationInitializer
您可以在下面找到一个示例:
public class Initializer extends AbstractHttpSessionApplicationInitializer { (1)
public Initializer() {
super(Config.class); (2)
}
}
类的名称 () 无关紧要。重要的是,我们将 .Initializer AbstractHttpSessionApplicationInitializer |
1 | 第一步是扩展 .这确保了一个名为 Spring bean 的 Servlet 容器被注册到我们的 Servlet 容器中,并用于每个 HTTP 请求。AbstractHttpSessionApplicationInitializer springSessionRepositoryFilter |
2 | AbstractHttpSessionApplicationInitializer 还提供了一种机制,可轻松允许 Spring 加载
我们的班级。Config |
基于 Apache Geode 对等 (P2P) XML 的配置
本节介绍如何配置 Apache Geode 的点对点 (P2P) 拓扑以管理状态
使用基于 XML 的配置。HttpSession
使用 XML 的 HttpSession with Apache Geode (P2P) 提供了一个工作示例,演示如何
将 Spring Session 与 Apache Geode 集成,以使用 XML 配置管理状态。您可以阅读
通过下面的基本集成步骤,但我们鼓励您按照详细的 'HttpSession' 进行操作
与 Apache Geode (P2P) 集成时,使用 XML 指南。HttpSession |
Spring XML 配置
添加所需的依赖项和存储库声明后,我们可以创建 Spring 配置。
Spring 配置负责创建一个,该配置将 替换为 Spring Session 和 Apache Geode 支持的实现。Servlet
Filter
javax.servlet.http.HttpSession
添加以下 Spring 配置:
<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”
如果未指定。Properties Cache |
2 | 我们必须配置 Apache Geode 对等实例。我们使用 Apache Geode 属性对其进行初始化。Cache |
3 | 最后,我们通过注册 .GemFireHttpSessionConfiguration |
有关为 Apache Geode 配置 Spring Data 的更多信息,请参阅参考指南。 |
XML Servlet 容器初始化
Spring XML 配置创建了一个名为 的 Spring Bean,该 Bean 实现 .该 Bean 负责将 替换为由 Spring Session 和 Apache Geode 支持的自定义实现。springSessionRepositoryFilter
javax.servlet.Filter
springSessionRepositoryFilter
javax.servlet.http.HttpSession
为了让我们发挥它的魔力,我们需要指示 Spring 加载我们的配置文件。Filter
session.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 配置文件。contextConfigLocation
最后,我们需要确保我们的 Servlet 容器(即 Tomcat)对每个 HTTP 请求都使用我们的容器。springSessionRepositoryFilter
以下代码片段为我们执行了最后一步:
<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 请求
,委托给 .springSessionRepositoryFilter
Filter
DelegatingFilterProxy
springSessionRepositoryFilter
3.3. 使用带有属性的 Apache Geode 配置管理HttpSession
虽然 Comments 在开始使用 Spring Session 时易于使用和方便
和 Apache Geode 在 Spring Boot 应用程序中迁移时,您很快就会遇到限制
环境转换为另一个环境,例如,从 DEV 迁移到 QA 再到 PROD 时。@EnableGemFireHttpSession
使用 annotation 属性,无法将配置从一个
环境到另一个。因此,Spring Session for Apache Geode 引入了众所周知的、记录在案的属性
对于所有 annotation 属性。@EnableGemFireHttpSession
@EnableGemFireHttpSession
财产 | Annotation 属性 | 描述 | 违约 |
---|---|---|---|
spring.session.data.gemfire.cache.client.pool.name |
|
客户端区域存储/访问 Session 状态使用的专用池的名称。 |
gemfirePool |
spring.session.data.gemfire.cache.client.region.shortcut |
|
在客户端-服务器拓扑中设置客户端区域数据管理策略。 |
ClientRegionShortcut.代理 |
spring.session.data.gemfire.cache.server.region.shortcut |
|
在对等 (P2P) 拓扑中设置对等区域数据管理策略。 |
RegionShortcut.PARTITION 分区 |
spring.session.data.gemfire.session.attributes.indexable |
|
要在 Session 区域中编制索引的 Session 属性的逗号分隔列表。 |
|
spring.session.data.gemfire.session.expiration.bean-name |
|
实现过期策略的 Spring 容器中的 Bean 的名称 |
|
spring.session.data.gemfire.session.expiration.max-inactive-interval-seconds |
|
会话过期超时(秒) |
1800 |
spring.session.data.gemfire.session.region.name |
|
用于存储和访问 Session 状态的客户端或对等区域的名称。 |
ClusteredSpringSessions 集群 |
spring.session.data.gemfire.session.serializer.bean-name |
|
实现序列化策略的 Spring 容器中的 Bean 的名称 |
SessionPdxSerializer |
所有属性也都记录在 annotation 属性 Javadoc 中。@EnableGemFireHttpSession |
因此,在使用 Apache Geode 时,调整 Spring Session 的配置非常简单 作为您的提供商,如下所示:
@SpringBootApplication
@ClientCacheApplication
@EnableGemFireHttpSession(maxInactiveIntervalInSeconds = 900)
class MySpringSessionApplication {
// ...
}
然后,在 :application.properties
#application.properties
spring.session.data.gemfire.cache.client.region.shortcut=CACHING_PROXY
spring.session.data.gemfire.session.expiration.max-inactive-internval-seconds=3600
显式定义的任何属性都会覆盖相应的 annotation 属性。@EnableGemFireHttpSession
在上面的示例中,即使 annotation 属性
设置为秒或 15 分钟,则相应的属性属性
(即 )
覆盖该值并将 Expiration (过期时间) 设置为 seconds (秒) 或 60 分钟。EnableGemFireHttpSession
maxInactiveIntervalInSeconds
900
spring.session.data.gemfire.session.expiration.max-inactive-interval-seconds
3600
请记住,属性会在运行时覆盖 annotation 属性值。 |
3.3.1. 属性的属性
您甚至可以变得更复杂,并使用其他属性配置您的属性,如下所示:
#application.properties
spring.session.data.gemfire.session.expiration.max-inactive-internval-seconds=${app.geode.region.expiration.timeout:3600}
此外,您可以使用 Spring 配置文件根据环境改变过期超时(或其他属性) 或您的应用程序,或者您的应用程序要求的任何标准。
属性占位符和嵌套是核心 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
@EnableGemFireHttpSession
这在概念上类似于 Spring Web MVC 的 Configurer 接口
(例如),它调整 Web 应用程序的
配置,例如配置异步支持。声明和实现 a 的优点是,它允许您对配置进行编程控制。这在您需要的情况下非常有用
轻松表达确定是否应应用配置的复杂条件逻辑。SpringSessionGemFireConfigurer
o.s.web.servlet.config.annotation.WebMvcConfigurer
Configurer
例如,要像以前一样调整 client Region data management policy (客户端区域数据管理策略) 和 Session expiration timeout (会话过期超时),请执行以下操作: 使用以下内容:
@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 的 Comments,如下所示:Configurer
@Value
@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 定义。@Value PropertySourcesPlaceholderConfigurer |
但是,您一次只能在 Spring 容器中声明 1 个 bean,除非
您还在使用 Spring 配置文件,或者已将多个 bean 中的 1 个标记为 primary
通过使用 Spring 的 context Comments 来获取。SpringSessionGemFireConfigurer
SpringSessionGemFireConfigurer
@Primary
3.4.1. 配置优先级
A 优先于注释属性
或任何已知且记录在 案的 Spring Session for Apache Geode 属性
(例如)
在 Spring Boot 中定义SpringSessionGemFireConfigurer
@EnableGemFireHttpSession
spring.session.data.gemfire.session.expiration.max-inactive-interval-seconds
application.properties.
如果您的 Web 应用程序使用了 1 种以上的配置方法,则以下优先级将适用:
-
SpringSessionGemFireConfigurer
“已实现” 回调方法 -
记录的 Spring Session for Apache Geode 属性(参见相应的注释 属性 Javadoc;例如
@EnableGemFireHttpSession
spring.session.data.gemfire.session.region.name
) -
@EnableGemFireHttpSession
注释属性
Spring Session for Apache Geode 小心翼翼地只应用来自 Bean 的配置
在 Spring 容器中声明。SpringSessionGemFireConfigurer
在上面的示例中,由于您没有实现该方法,因此 Apache Geode 区域的名称
管理状态将不由 Configurer 决定。getRegionName()
HttpSession
例
例如,请考虑以下配置:
@ClientCacheApplication
@EnableGemFireHttpSession(
maxInactiveIntervalInSeconds = 3600,
poolName = "DEFAULT"
)
class MySpringSessionConfiguration {
@Bean
SpringSessionGemFireConfigurer sessionExpirationTimeoutConfigurer() {
return new SpringSessionGemFireConfigurer() {
@Override
public int getMaxInactiveIntervalInSeconds() {
return 300;
}
};
}
}
此外,请考虑以下 Spring Boot 文件:application.properties
-
Spring Boot
application.properties
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.maxInactiveIntervalInSeconds
由于 “sessionExpirationTimeoutConfigurer” Bean 不会覆盖该方法,因此 Session Region
name 将由属性设置为 “Sessions” 的属性 (i.e.) 确定,
这将覆盖 implicit annotation 属性的默认值
“ClusteredSpringSessions” 的 ClusteredSpringSessions 中。getRegionName()
spring.session.data.gemfire.session.region.name
@EnableGemFireHttpSession.regionName
annotation 属性的值 “DEFAULT” 将决定存储池的名称
在客户端和服务器之间发送 Region 操作以管理服务器上的 Session 状态时使用,因为
设置了相应的属性(即 spring.session.data.gemfire.cache.client.pool.name'),也未设置
该方法被“sessionExpirationTimeoutConfigurer”Bean 覆盖。@EnableGemFireHttpSession.poolName
SpringSessionGemFireConfigurer.getPoolName()
最后,用于管理 Session 状态的客户端区域将具有 的数据管理策略 ,默认
value (未显式设置的 annotation 属性),或者
是此属性的相应属性(即 )。
并且,由于该方法未被覆盖,因此使用默认值。PROXY
@EnableGemFireHttpSession.clientRegionShortcut
spring.session.data.gemfire.cache.client.region.shortcut
SpringSessionConfigurer.getClientRegionShortcut()
3.5. Apache Geode 过期
默认情况下,Apache Geode 使用 过期超时为 30 分钟,并将 INVALIDATE 条目作为操作。这意味着当用户的 Session 保持非活动状态时 (即空闲)超过 30 分钟,Session 将过期并失效,用户必须开始新的 Session 以便继续使用该应用程序。
但是,如果您对会话状态管理和过期以及使用 默认的空闲超时 (TTI) 过期策略不足以满足您的用例 (UC) 需求?
现在,Spring Session for Apache Geode 支持特定于应用程序的自定义过期策略。作为应用程序 开发者,你可以指定自定义规则来管理由 Spring Session 管理的 Session 的过期,由 Apache Geode 的 Apache。
Spring Session for Apache Geode 提供了新的 Strategy 接口。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。
使用 annotation, 属性配置
实现 Session 过期的自定义应用程序策略和规则的 Bean。@EnableGemFireHttpSession
sessionExpirationPolicyBeanName
SessionExpirationPolicy
例如:
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 类中,简单地声明以下内容:
SessionExpirationPolicy
@SpringBootApplication
@EnableGemFireHttpSession(
maxInactiveIntervalInSeconds = 600,
sessionExpirationPolicyBeanName = "expirationPolicy"
)
class MySpringSessionApplication {
@Bean
SessionExpirationPolicy expirationPolicy() {
return new MySessionExpirationPolicy();
}
}
或者,可以使用该属性配置 Bean 的名称,也可以通过在 Spring 容器中声明 Bean 并覆盖该方法来配置 Bean 的名称。SessionExpirationPolicy spring.session.data.gemfire.session.expiration.bean-name SpringSessionGemFireConfigurer getSessionExpirationPolicyBeanName() |
您只需要实现方法
它封装了规则以确定 Session 何时到期。Session 的过期超时
表示为 of ,它指定 Session 过期之前的时间长度。determineExpirationTimeout(:Session):Optional<Duration>
Optional
java.time.Duration
该方法可以是特定于 Session 的,并且可能会随着每次调用而更改。determineExpirationTimeout
或者,您可以实现该方法以指定 Session 过期时执行的操作。默认情况下,
区域条目(即 Session)无效。另一种选择是在过期时销毁 Region Entry,
这将删除键 (Session ID) 和值 (Session)。Invalidate 仅删除该值。getAction
在后台,它被改编成 Apache Geode CustomExpiry 接口的实例。
然后,将此 Spring Session 对象设置为 Session Region 的自定义条目空闲超时过期策略。SessionExpirationPolicy CustomExpiry |
在确定过期期间,每次运行过期线程时,都会为区域中的每个条目(即 Session)调用该方法,这反过来又会
调用我们的方法。
返回的 S 将转换为秒,并在从 CustomExpiry.getExpiry(..) 方法调用返回的 ExpirationAttributes 中用作过期超时。CustomExpiry.getExpiry(:Region.Entry<String, Session>):ExpirationAttributes SessionExpirationPolicy.determineExpirationTimout(:Session):Optional<Duration> java.time.Duration |
Apache Geode 的过期线程每秒运行一次,评估区域中的每个条目(即会话)
以确定条目是否已过期。您可以使用该属性控制过期线程数。有关更多详细信息,请参阅 Apache Geode 文档。gemfire.EXPIRY_THREADS |
3.5.1. Expiration Timeout 配置
如果要根据自定义的过期超时
annotation、attribute 或
相应的属性
那么你的自定义实现也可以实现 interface.SessionExpirationPolicy
@EnableGemFireHttpSession
maxInactiveIntervalInSeconds
spring.session.data.gemfire.session.expiration.max-inactive-interval-seconds
SessionExpirationPolicy
SessionExpirationTimeoutAware
接口定义为:SessionExpirationTimeoutAware
interface SessionExpirationTimeoutAware {
void setExpirationTimeout(Duration expirationTimeout);
}
当您的自定义实现还实现了接口
则 Spring Session for Apache Geode 将为您的实现提供来自注释、属性或属性(如果已设置)的值,或者来自 Spring 应用程序上下文中声明的任何 Bean 的值,作为 .SessionExpirationPolicy
SessionExpirationTimeoutAware
@EnableGemFireHttpSession
maxInactiveIntervalInSeconds
spring.session.data.gemfire.session.expiration.max-inactive-interval-seconds
SpringSessionGemFireConfigurer
java.time.Duration
如果使用了 1 个以上的配置选项,则以下顺序优先:
-
SpringSessionGemFireConfigurer.getMaxInactiveIntervalInSeconds()
-
spring.session.data.gemfire.session.expiration.max-inactive-interval-seconds
财产 -
@EnableGemFireHttpSession
注释, 属性maxInactiveIntervalInSeconds
3.5.2. 固定超时过期
为了更加方便,Spring Session for Apache Geode 提供了固定持续时间过期(或核心 Spring Session Issue #922 中描述的“绝对会话超时”)的接口实现。SessionExpirationPolicy
在某些情况下,例如出于安全原因,可能需要在固定 时间长度 (例如每小时),无论用户的 Session 是否仍处于活动状态。
Spring Session for Apache Geode 提供了开箱即用的实现
对于此确切的用例 (UC)。除了处理固定期限到期外,还要小心地仍然考虑
并应用默认的 Idle Expiration 超时。FixedTimeoutSessionExpirationPolicy
例如,考虑这样一个场景:用户登录,开始一个会话,处于活动状态 10 分钟,然后离开 让 Session 处于空闲状态。如果固定持续时间过期超时设置为 60 分钟,但空闲过期 超时仅设置为 30 分钟,并且用户未返回,则 Session 应在 40 分钟后过期 而不是 60 分钟,此时将发生固定持续时间过期。
相反,如果用户忙碌了整整 40 分钟,从而使 Session 保持活动状态,从而避免了 30 分钟 idle expiration timeout,然后离开,那么我们的固定持续时间过期超时应该开始并过期 用户的 Session 时间,即使用户的空闲过期超时要到 70 分钟才会发生 in(40 分钟 (活动) + 30 分钟 (空闲) = 70 分钟)。
嗯,这正是 this 所做的。FixedTimeoutSessionExpirationPolicy
要配置 ,请执行以下操作:FixedTimeoutSessionExpirationPolicy
@SpringBootApplication
@EnableGemFireHttpSession(sessionExpirationPolicyBeanName = "fixedTimeoutExpirationPolicy")
class MySpringSessionApplication {
@Bean
SessionExpirationPolicy fixedTimeoutExpirationPolicy() {
return new FixedTimeoutSessionExpirationPolicy(Duration.ofMinutes(60L));
}
}
在上面的示例中,在 Spring 应用程序上下文中将 声明为 bean
并使用 60 分钟的固定持续时间过期超时进行初始化。因此,用户的 Session 将
在空闲超时(默认为 30 分钟)或固定超时(配置为 60 分钟)后过期,
哪个先发生。FixedTimeoutSessionExpirationPolicy
还可以使用
适用于 Apache Geode 的 Spring 会话。此 BPP 包装
实施中特定于任何数据存储
,仅评估 Sessions 在访问时过期。此方法与基础数据存储无关
因此可以与任何 Spring Session 提供程序一起使用。到期确定完全基于
Session 属性和 required 指定固定持续时间
过期超时。FixedDurationExpirationSessionRepositoryBeanPostProcessor SessionRepository FixedDurationExpirationSessionRepository creationTime java.time.Duration |
不应在严格的过期超时情况下使用 ,例如
当 Session 必须在固定持续时间过期超时后立即过期时。此外,与
的 , 不采用空闲过期
timeout 的考虑。也就是说,在确定过期超时时,它只使用固定持续时间
对于给定的 Session。FixedDurationExpirationSessionRepository FixedTimeoutSessionExpirationPolicy FixedDurationExpirationSessionRepository |
3.5.3. 链接SessionExpirationPolicy
使用复合软件设计模式,您可以将一组实例视为单个实例,其功能就像在链中一样,就像
Servlet 过滤器本身。SessionExpirationPolicy
复合软件设计模式是一种功能强大的模式,由 , 提供支持,只需返回 of from
方法。SessionExpirationPolicy
@FunctionalInterface
Optional
java.time.Duration
determineExpirationTimeout
这允许每个组合仅在
可以由此实例确定。或者,此实例可以传送到合成中的下一个实例,也可以链接,直到返回非空过期超时,或者最终返回
不返回过期超时。SessionExpirationPolicy
Duration
SessionExpirationPolicy
事实上,这个策略是由 内部使用的,如果空闲超时发生在固定超时之前,它将返回。通过返回
无过期超时,Apache Geode 将遵循默认的、配置的条目空闲超时过期策略
在管理 Session 状态的区域上。FixedTimeoutSessionExpirationPolicy
Optional.empty()
3.6. Apache Geode 序列化
为了在客户端和服务器之间传输数据,或者在对等节点之间分发和复制数据 在集群中,数据必须序列化。在这种情况下,有问题的数据是 Session 的状态。
每当 Session 在 client/server 拓扑中被持久化或访问时,Session 的状态都会通过网络发送。 通常,启用了 Spring Session 的 Spring Boot 应用程序将是集群中服务器的客户端 Apache Geode 节点。
在服务器端,Session 状态可能分布在集群中的多个服务器(数据节点)之间进行复制 数据,并保证 Session 状态的高可用性。使用 Apache Geode 时,可以对数据进行分区, 或 sharded,并且可以指定 redundancy-level 。当分发数据以进行复制时,它还必须 serialized 在集群中的 Peer 节点之间传输 Session 状态。
开箱即用的 Apache Geode 支持 Java 序列化。Java 序列化有很多优点, 例如处理对象图中的循环,或者被任何用 Java 编写的应用程序普遍支持。 但是,Java 序列化非常冗长,并不是最有效的在线格式。
因此,Apache Geode 提供了自己的序列化框架来序列化 Java 类型:
3.6.1. Apache Geode 序列化背景
如上所述,Apache Geode 提供了 2 个额外的序列化框架:数据序列化和 PDX 序列化。
数据序列化
数据序列化是一种非常有效的格式(即快速和紧凑),与 Java 序列化相比开销很小。
它通过发送 只发送实际更改的数据位,而不是发送整个对象,这肯定会减少 除了在持久保存数据时减少 IO 量外,还关注通过网络发送的数据量 或溢出到磁盘。
但是,每当数据通过网络传输或持久化/溢出到
并从磁盘访问,因为接收端执行反序列化。事实上,无论何时使用 Delta Propagation,都必须在接收端对对象进行反序列化,以便应用 “delta”。Apache Geode 适用
deltas 的 deltas 方法。显然,你不能
在序列化对象上调用方法。org.apache.geode.Delta
PDX
另一方面,PDX 代表便携式数据交换,它保留了发送数据的形式。
例如,如果客户端以 PDX 格式将数据发送到服务器,则服务器会将数据保留为 PDX 序列化字节
并将它们存储在数据访问操作所针对的缓存中。Region
此外,PDX,顾名思义,是“可移植的”,这意味着它支持 Java 和本地语言客户端。 例如 C、C++ 和 C# 客户端,以对同一数据集进行互操作。
PDX 甚至允许对序列化的字节执行 OQL 查询,而不会导致对象被反序列化 首先,以便评估查询谓词并执行查询。这可以从 Apache Geode 开始实现 维护一个 “Type Registry”,其中包含被序列化和存储的对象的类型元数据 使用 PDX 的 Apache Geode。
但是,可移植性确实有成本,其开销略高于数据序列化。尽管如此,PDX 还很遥远 比 Java 序列化更高效、更灵活,Java 序列化将类型元数据存储在对象的序列化字节中 而不是像 Apache Geode 在使用 PDX 时那样在单独的类型注册表中。
PDX 不支持 Delta。从技术上讲,PDX 可序列化对象可以通过实现
org.apache.geode.Delta
接口,并且只有 “delta” 将是
发送的,即使在 PDX 的上下文中也是如此。但是,必须反序列化 PDX 序列化对象才能应用增量。
请记住,调用一个方法来应用 delta,这首先违背了使用 PDX 的目的。
在开发管理 {data-store-name} 集群中数据的 Native Client(例如 C)时,甚至在混合 具有 Java 客户端的 Native Client,通常不会在 Classpath 上提供任何关联的 Java 类型 集群中 的服务器。使用 PDX,无需在 Classpath 上提供 Java 类型,并且许多 仅开发和使用 Native Client 来访问存储在 {data-store-name} 中的数据的用户将不会提供任何 Java 类型。
Apache Geode 还支持序列化为 PDX 或从 PDX 序列化的 JSON。在这种情况下,Java 类型很可能不会 在服务器 Classpath 上提供,因为支持 JSON 的许多不同语言(例如 JavaScript、Python、Ruby)可以是 与 Apache Geode 一起使用。
尽管如此,即使 PDX 正在运行,用户也必须注意不要在集群中的服务器上导致 PDX 序列化对象 进行反序列化。
例如,考虑对序列化为 PDX...
@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 查询在对象上调用方法,例如:Person
SELECT * FROM /People p WHERE p.age >= 21
然后,这将导致 PDX 序列化对象被反序列化,因为 不是 ,
而是一个包含基于另一个字段 的计算的方法(即 )。同样,调用
OQL 查询中的任何方法(如 )都将导致反序列化的发生
也。Person
age
Person
Person
birthDate
java.lang.Object
Object.toString()
Apache Geode 确实提供读取序列化
配置设置,以便可能在 内部调用的任何缓存操作不会导致 PDX 序列化对象被反序列化。但是,没有什么能阻止构思不周的 OQL 查询
导致反序列化,所以要小心。Region.get(key)
Function
数据序列化 + PDX + Java 序列化
Apache Geode 可以同时支持所有 3 种序列化格式。
例如,您的应用程序域模型可能包含实现接口
并且您可能正在使用 Data Serialization 框架和 PDX 的组合。java.io.Serialiable
虽然可以将 Java 序列化与 Data Serialization 和 PDX 一起使用,但通常更可取 ,建议使用 1 个序列化策略。 |
与 Java 序列化不同,数据序列化和 PDX 序列化不处理对象图周期。 |
有关 Apache Geode 序列化机制的更多背景信息,请参阅此处。
3.6.2. 使用 Spring Session 进行序列化
以前,Spring Session for Apache Geode 仅支持 Apache Geode 数据序列化格式。主要的 这背后的动机是利用 Apache Geode 的 Delta Propagation 功能,因为 Session 的 state 可以是任意大的。
但是,从 Spring Session for Apache Geode 2.0 开始,PDX 也受支持,现在是新的默认序列化 选择。在 Spring Session for Apache Geode 2.0 中,默认值更改为 PDX,主要是因为 PDX 是最 用户广泛使用和请求的格式。
PDX 无疑是最灵活的格式,以至于您甚至不需要 Spring Session for Apache Geode 或其对集群中服务器的 Classpath 的任何传递依赖项,以使用 Spring Session Apache Geode 的 Apache。事实上,使用 PDX,您甚至不需要将应用程序域对象类型存储在 服务器的 Classpath 上的 (HTTP) Session。
实质上,在使用 PDX 序列化时,Apache Geode 不需要存在关联的 Java 类型 在服务器的 Classpath 上。只要集群中的服务器上没有发生反序列化,您就是安全的。
该注解引入了一个新属性,即用户
可用于配置在 Spring 容器中声明和注册的 bean 的名称,该 bean 实现了所需的
序列化策略。Spring Session for Apache Geode 使用序列化策略进行序列化
Session 状态。@EnableGemFireHttpSession
sessionSerializerBeanName
Spring Session for Apache Geode 提供 2 种开箱即用的序列化策略:1 种用于 PDX,1 种用于数据序列化。它会自动在 Spring 容器中注册两个序列化策略 bean。 但是,这些策略中只有 1 种在运行时实际使用,即 PDX!
在实现数据序列化和 PDX 的 Spring 容器中注册的 2 个 bean 分别命名为 和 。默认情况下,属性
设置为 ,就像用户注释了他/她的 Spring Boot、启用了 Spring Session 的应用程序一样
configuration 类替换为:SessionDataSerializer
SessionPdxSerializer
sessionSerializerBeanName
SessionPdxSerializer
@SpringBootApplication
@EnableGemFireHttpSession(sessionSerializerBeanName = "SessionPdxSerializer")
class MySpringSessionApplication { }
通过将属性设置为 ,将序列化策略更改为 Data Serialization 是一件简单的事情,如下所示:sessionSerializerBeanName
SessionDataSerializer
@SpringBootApplication
@EnableGemFireHttpSession(sessionSerializerBeanName = "SessionDataSerializer")
class MySpringSessionApplication { }
由于这两个值非常常见,因此 Spring Session for Apache Geode 为类中的每个值提供常量: 和 。因此,您可以显式配置 PDX,
如下:GemFireHttpSessionConfiguration
GemFireHttpSessionConfiguration.SESSION_PDX_SERIALIZER_BEAN_NAME
GemFireHttpSessionConfiguration.SESSION_DATA_SERIALIZER_BEAN_NAME
@SpringBootApplication
@EnableGemFireHttpSession(sessionSerializerBeanName = GemFireHttpSessionConfiguration.SESSION_PDX_SERIALIZER_BEAN_NAME)
class MySpringSessionApplication { }
使用 1 个属性和 2 个开箱即用的 bean 定义,您可以指定所需的序列化框架 与由 Apache Geode 支持的支持 Spring Session 的 Spring Boot 应用程序一起使用。
3.6.3. Spring Session for Apache Geode 序列化框架
为了抽象出 Apache Geode 的数据序列化和 PDX 序列化框架的细节, Spring Session for Apache Geode 提供了自己的序列化框架(门面),将 Apache Geode 的 序列化框架。
序列化 API 存在于包下。主要
此 API 中的接口是 .org.springframework.session.data.gemfire.serialization
org.springframework.session.data.gemfire.serialization.SessionSerializer
接口定义为:
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 对象。Session
这些类型的 and 类型参数和相应的方法参数提供对对象的引用
负责将 写入字节流或从字节流中读取。实际的
参数将特定于类型,具体取决于配置的基础 Apache Geode 序列化策略。IN
OUT
Session
Session
例如,当使用 Apache Geode 的 PDX 序列化框架时,将分别是 和 的实例。配置 Apache Geode 的数据序列化框架后,则 和 将分别是 和 的实例。IN
OUT
org.apache.geode.pdx.PdxReader
org.apache.geode.pdx.PdxWriter
IN
OUT
java.io.DataInput
java.io.DataOutput
这些参数由框架自动提供给实现,并且作为
前面提到的,是基于配置的底层 Apache Geode 序列化策略。SessionSerializer
从本质上讲,尽管 Spring Session for Apache Geode 为 Apache Geode 的 序列化框架,在后台 Apache Geode 仍然需要这些序列化框架之一 用于将数据序列化到 Apache Geode 或从 Apache Geode 序列化数据。
那么 SessionSerializer
接口的真正用途是什么呢?
实际上,它允许用户自定义 Session 状态的哪些方面实际被序列化和存储
在 Apache Geode 中。应用程序开发人员可以提供他们自己的自定义的、特定于应用程序的实现,在 Spring 容器中将其注册为 Bean,然后将其配置为由 Spring Session 使用
用于序列化 Session 状态,如下所示:SessionSerializer
@EnableGemFireHttpSession(sessionSerializerBeanName = "MyCustomSessionSerializer")
class MySpringSessionDataGemFireApplication {
@Bean("MyCustomSessionSerializer")
SessionSerializer<Session, ?, ?> myCustomSessionSerializer() {
// ...
}
}
实现 SessionSerializer
Spring Session for Apache Geode 在用户想要实现适合 Apache Geode 的序列化框架之一的自定义时提供帮助。SessionSerializer
如果用户只是实现接口
直接扩展,而无需从 Spring Session for Apache Geode 提供的抽象基类之一扩展,相关的
添加到 Apache Geode 的 Serialization 框架之一,则 Spring Session for Apache Geode 会将用户的
自定义实现,并将其作为 .org.springframework.session.data.gemfire.serialization.SessionSerializer
SessionSerializer
org.springframework.session.data.gemfire.serialization.pdx.support.PdxSerializerSessionSerializerAdapter
org.apache.geode.pdx.PdxSerializer
Spring Session for Apache Geode 小心翼翼地避免STOMP踏用户
可能已经通过其他方式向 Apache Geode 注册。事实上,有几种不同的,只要
存在 Apache Geode 接口的实现:PdxSerializer
org.apache.geode.pdx.PdxSerializer
-
Apache Geode 本身提供
org.apache.geode.pdx.ReflectionBasedAutoSerializer
。 -
Spring Data for Apache Geode (SDG) 提供了
org.springframework.data.gemfire.mapping.MappingPdxSerializer
, 它用于 SD 存储库抽象和 SDG 的扩展,以处理将 PDX 序列化类型映射到 在应用程序存储库界面中定义的应用程序域对象类型。
这是通过获取缓存上任何当前注册的实例并对其进行组合来实现的
包装用户的自定义应用程序实现并在 Apache Geode 缓存上重新注册此 “复合”。“复合”实现由 Spring Session for Apache Geode 的类提供
当实体作为 PDX 存储在 Apache Geode 中时。PdxSerializer
PdxSerializerSessionSerializerAdapter
SessionSerializer
PdxSerializer
PdxSerializer
org.springframework.session.data.gemfire.pdx.support.ComposablePdxSerializer
如果当前没有其他 API 注册到 Apache Geode 缓存中,则适配器
只是注册了。PdxSerializer
当然,您可以通过执行以下 1 项操作来强制将基础 Apache Geode 序列化策略与自定义实现一起使用:SessionSerializer
-
自定义实现可以实现 Apache Geode 的接口,或者为方便起见,扩展 Spring Session for Apache Geode 的类 Spring Session for Apache Geode 会将自定义注册为 a 到 Apache Geode。
SessionSerializer
org.apache.geode.pdx.PdxSerializer
org.springframework.session.data.gemfire.serialization.pdx.AbstractPdxSerializableSessionSerializer
SessionSerializer
PdxSerializer
-
自定义实现可以扩展 Apache Geode 的类,或者为方便起见,扩展 Spring Session for Apache Geode 的类 Spring Session for Apache Geode 会将自定义注册为 a 到 Apache Geode。
SessionSerializer
org.apache.geode.DataSerializer
org.springframework.session.data.gemfire.serialization.data.AbstractDataSerializableSessionSerializer
SessionSerializer
DataSerializer
-
最后,用户可以像以前一样创建自定义实现,而无需指定哪个 Apache Geode 序列化框架,因为自定义实现未实现 任何 Apache Geode 序列化接口或从 Spring Session for Apache Geode 提供的任何 抽象基类,并且仍然在 Apache Geode 中将其注册为 a,方法是声明 在 Spring 容器中的附加 Spring Session for Apache Geode bean 类型为 ,如下所示...
SessionSerializer
SessionSeriaizer
DataSerializer
org.springframework.session.data.gemfire.serialization.data.support.DataSerializerSessionSerializerAdapter
@EnableGemFireHttpSession(sessionSerializerBeanName = "customSessionSerializer")
class Application {
@Bean
DataSerializerSessionSerializerAdapter dataSerializerSessionSerializer() {
return new DataSerializerSessionSerializerAdapter();
}
@Bean
SessionSerializer<Session, ?, ?> customSessionSerializer() {
// ...
}
}
只是因为 Spring 容器中注册为 bean 的存在,
任何中性自定义实现都将被视为 Apache Geode 中的一个。DataSerializerSessionSerializerAdapter
SessionSerializer
DataSerializer
对数据序列化的额外支持
如果您正在配置和引导 Apache Geode 服务器,请随时跳过本节 在您的集群中使用 Spring (Boot),因为通常以下信息将不适用。答案是肯定的 这完全取决于你声明的依赖项和 Spring 配置。但是,如果您使用 Gfsh 启动集群中的服务器,那么请务必继续阅读。 |
背景
使用 Apache Geode 的 DataSerialization 框架时,尤其是在序列化 (HTTP) 会话时从客户端 状态添加到集群中的服务器,则必须注意在集群中配置 Apache Geode 服务器 替换为适当的依赖项。如前一节所述,在利用增量时尤其如此 在 Data Serialization 上。
当使用 DataSerialization 框架作为序列化策略来序列化 (HTTP) 会话状态时 你的 Web 应用程序客户端连接到服务器,那么服务器必须正确地配置 Spring Session ,用于表示 (HTTP) 会话及其内容的 Apache Geode 类类型。这意味着包括 服务器 Classpath 上的 Spring JAR。
此外,使用 DataSerialization 可能还需要包含包含应用程序域的 JAR 类,这些类由 Web 应用程序使用,并作为 Session Attribute 值放入 (HTTP) Session 中, 特别是在以下情况下:
-
您的类型实现接口。
org.apache.geode.DataSerializable
-
您的类型实现接口。
org.apache.geode.Delta
-
您已注册一个 用于标识和序列化类型。
org.apache.geode.DataSerializer
-
您的类型实现接口。
java.io.Serializable
当然,您必须确保放置在 (HTTP) Session 中的应用程序域对象类型在某些 形式或其他形式。但是,并非严格要求您使用 DataSerialization,也不必如此 在以下情况下,需要将应用程序域对象类型放在 servers 类路径上:
-
您的类型实现接口。
org.apache.geode.pdx.PdxSerializable
-
或者,您已经注册了一个正确标识和序列化 您的应用程序域对象类型。
org.apache.geode.pdx.PdxSerializer
Apache Geode 在确定要使用的序列化策略时,将应用以下优先顺序 要序列化对象图:
-
首先,对象和/或任何已注册的标识要序列化的对象。
DataSerializable
DataSerializers
-
然后 objects 和/或任何已注册的标识要序列化的对象。
PdxSerializable
PdxSerializer
-
最后,所有类型。
java.io.Serializable
这也意味着,如果特定的应用程序域对象类型(例如 )实现 ,
但是,已向 Apache Geode 注册了一个 (custom) 以标识相同的应用程序
domain 对象类型(即 ),则 Apache Geode 将使用 PDX 来序列化 “A” 而不是 Java 序列化,
在这种情况下。A
java.io.Serializable
PdxSerializer
A
这特别有用,因为您可以使用 DataSerialization 来序列化 (HTTP) Session 对象,利用 增量和 DataSerialization 的所有强大功能,但随后使用 PDX 序列化应用程序域对象 类型,这大大简化了所涉及的配置和/或工作。
现在我们已经大致了解了为什么存在这种支持,您如何启用它?
配置
首先,创建一个 Apache Geode ,如下所示:cache.xml
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* 中使用以下命令启动您的服务器:
gfsh> start server --name=InitializedServer --cache-xml-file=/path/to/cache.xml --classpath=...
使用适当的依赖项配置 Apache Geode 服务器是棘手的部分,
但一般来说,以下内容应该有效: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 中。
要全面了解其工作原理,请参阅示例。
自定义变化检测
默认情况下,每当 Session 被修改(例如,更新到当前时间)时,Session
被 Spring Session for Apache Geode (SSDG) 视为脏的。在使用 Apache Geode 数据序列化框架时,利用 Apache Geode 的增量传播功能也非常有用和有价值。lastAccessedTime
使用数据序列化时,SSDG 还使用增量传播仅发送对 Session 状态的更改 客户端和服务器。这包括可能已添加、删除或更新的任何 Session 属性。
默认情况下,只要调用了 session,Session 属性就被认为是 “dirty”
,并将在 Client 端和 Server 之间的 delta 中发送。即使您的应用程序域对象
未更改。Session.setAttribute(name, value)
通常,除非您的对象已更改,否则永远不会有理由调用然而
如果发生这种情况,并且您的对象相对较大(具有复杂的对象层次结构),则可能需要
请考虑以下任一内容:Session.setAttribute(..)
-
在应用程序域对象中实现 Delta 接口 模型虽然有用,但侵入性很强,或者......
-
提供 SSDG 策略接口的自定义实现。
org.springframework.session.data.gemfire.support.IsDirtyPredicate
SSDG 提供了 5 种开箱即用的策略接口实现:IsDirtyPredicate
类 | 描述 | 违约 |
---|---|---|
|
新的 Session 属性值始终被视为脏。 |
|
|
新的 Session 属性值永远不会被视为脏。 |
|
|
当旧值和新值
是不同的,如果新值的 type 未实现或新值的方法返回 true。 |
是的 |
|
如果旧值不等于
由 method 确定的新值。 |
|
|
如果旧值与
使用标识等于运算符的新值(即 )。 |
如上表所示,这是 SSDG 使用的默认实现。
这会自动考虑实现
Apache Geode 界面。但是,即使您的应用程序
domain 对象不实现接口。SSDG 会将您的应用程序域对象视为脏
每当调用时,如果新值与旧值不同,则
或者新值不实现接口。DeltaAwareDirtyPredicate
DeltaAwareDirtyPredicate
Delta
DeltaAwareDirtyPredicate
Delta
Session.setAttribute(name, newValue)
Delta
您只需在 Spring 容器中声明一个 bean 即可更改 SSDG 的脏实现、确定策略
接口类型中:IsDirtyPredicate
IsDirtyPredicate
@EnableGemFireHttpSession
class ApplicationConfiguration {
@Bean
IsDirtyPredicate equalsDirtyPredicate() {
return EqualsDirtyPredicate.INSTANCE;
}
}
组成
该接口还提供了 and 方法
在一个组合中组合 2 个或多个实现,以便组织复杂的逻辑和规则
用于确定应用程序域对象是否脏。IsDirtyPredicate
andThen(:IsDirtyPredicate)
orThen(:IsDirtyPredicate)
IsDirtyPredicate
例如,您可以同时使用 OR 运算符组合两者:EqualsDirtyPredicate
DeltaAwareDirtyPredicate
EqualsDirtyPredicate
DeltaAwareDirtyPredicate
@EnableGemFireHttpSession
class ApplicationConfiguration {
@Bean
IsDirtyPredicate equalsOrThenDeltaDirtyPredicate() {
return EqualsDirtyPredicate.INSTANCE
.orThen(DeltaAwareDirtyPredicate.INSTANCE);
}
}
您甚至可以根据特定的应用程序域对象类型实现自己的自定义:IsDirtyPredicates
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 谓词组合用于回退,如下所示:CustomerDirtyPredicate
AccountDirtyPredicate
IsDirtyPredicates
@EnableGemFireHttpSession
class ApplicationConfiguration {
@Bean
IsDirtyPredicate typeSpecificDirtyPredicate() {
return new CustomerDirtyPredicate()
.andThen(new AccountDirtyPredicate())
.andThen(IsDirtyPredicate.ALWAYS_DIRTY);
}
}
组合和可能性是无穷无尽的。
实施自定义策略时要小心。如果您错误地确定
application domain 对象不是脏的,那么它不会在 Session delta 中发送
从客户端到服务器。IsDirtyPredicate |
更改 Session 表示
在内部,Spring Session for Apache Geode 维护 (HTTP) Session 和 Session 的 属性。每种表示形式都基于是否支持 Apache Geode“增量”。
由于前面讨论的原因,在使用数据序列化时,只有 Spring Session for Apache Geode 才会启用 Apache Geode 增量传播。
实际上,该策略是:
-
如果配置了 Apache Geode 数据序列化,则支持 Deltas 并使用 and 表示形式。
DeltaCapableGemFireSession
DeltaCapableGemFireSessionAttributes
-
如果配置了 Apache Geode PDX 序列化,则将禁用增量传播 和 和 表示形式。
GemFireSession
GemFireSessionAttributes
可以覆盖 Spring Session for Apache Geode 和用户使用的这些内部表示
来提供自己的 Session 相关类型。唯一严格的要求是 Session 实现
必须实现核心 Spring Session 接口。org.springframework.session.Session
举个例子,假设你想定义自己的 Session 实现。
首先,定义类型。也许您的自定义类型甚至封装并处理了 Session
属性,而不必定义单独的类型。Session
Session
class MySession implements org.springframework.session.Session {
// ...
}
然后,您需要扩展类
并覆盖该方法以创建自定义实现类的实例。org.springframework.session.data.gemfire.GemFireOperationsSessionRepository
createSession()
Session
class MySessionRepository extends GemFireOperationsSessionRepository {
@Override
public Session createSession() {
return new MySession();
}
}
如果您提供自己的自定义实现,并且 Apache Geode PDX 序列化为
configured,然后您完成了。SessionSerializer
但是,如果您配置了 Apache Geode 数据序列化,则必须另外提供自定义
实现接口,并让它直接扩展 Apache Geode 的类,或者扩展 Spring Session for Apache Geode 的类
并覆盖该方法。SessionSerializer
org.apache.geode.DataSerializer
org.springframework.session.data.gemfire.serialization.data.AbstractDataSerializableSessionSerializer
getSupportedClasses():Class<?>[]
例如:
class MySessionSerializer extends AbstractDataSerializableSessionSerializer {
@Override
public Class<?>[] getSupportedClasses() {
return new Class[] { MySession.class };
}
}
不幸的是,无法返回通用的 Spring Session 接口类型。如果可以,那么我们可以避免显式需要覆盖
自定义实现。但是,Apache Geode 的数据序列化框架只能匹配
在确切的类类型上,因为它错误地在内部存储并按名称引用类类型,然后
要求用户重写并实现该方法。getSupportedClasses()
org.springframework.session.Session
getSupportedClasses()
DataSerializer
getSupportedClasses()
3.7. HttpSession 集成的工作原理
幸运的是,和 (用于
获取 ) 是接口。这意味着我们可以为每个 API 提供自己的实现。javax.servlet.http.HttpSession
javax.servlet.http.HttpServletRequest
HttpSession
本节介绍 Spring Session 如何提供与 的透明集成。
其目的是让用户了解后台发生的事情。此功能已实现
和 integrated 的,因此您无需自己实现此 logic。javax.servlet.http.HttpSession |
首先,我们创建一个自定义,该自定义返回 .它看起来像下面这样:javax.servlet.http.HttpServletRequest
javax.servlet.http.HttpSession
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.HttpSession
javax.servlet.http.HttpServletRequestWrapper
javax.servlet.http.HttpServletRequest
我们使用名为 .伪代码可以在下面找到:javax.servlet.http.HttpServletRequest
Filter
SessionRepositoryFilter
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.HttpServletRequest
FilterChain
Filter
javax.servlet.http.HttpSession
这凸显了为什么必须将 Spring Session 放在任何事情之前很重要
它与 .SessionRepositoryFilter
javax.servlet.http.HttpSession
3.8. HttpSession监听器
Spring Session 通过翻译和声明 into 来支持。HttpSessionListener
SessionCreatedEvent
SessionDestroyedEvent
HttpSessionEvent
SessionEventHttpSessionListenerAdapter
要使用此支持,您需要:
-
确保您的实施支持并配置为触发 and'SessionDestroyedEvent'。
SessionRepository
SessionCreatedEvent
-
配置为 Spring Bean。
SessionEventHttpSessionListenerAdapter
-
将 every 注入到
HttpSessionListener
SessionEventHttpSessionListenerAdapter
如果您将 HttpSession 中记录的配置支持与 Apache Geode 结合使用,
然后,您需要做的就是将 every 注册为 bean。HttpSessionListener
例如,假设您希望支持 Spring Security 的并发控制,并且需要使用 ,
然后,您可以简单地添加为 Bean。HttpSessionEventPublisher
HttpSessionEventPublisher
3.10. SessionRepository
A 负责创建、保存和访问实例和状态。SessionRepository
Session
如果可能,开发人员不应直接与 或 .相反,开发人员
应该更喜欢与 和 和 集成进行交互和间接交互。SessionRepository
Session
SessionRepository
Session
javax.servlet.http.HttpSession
WebSocket
WebSession
3.11. FindByIndexNameSessionRepository
Spring Session 使用 的最基本 API 是 .API 故意非常简单
这样就很容易提供具有基本功能的其他 implementations。Session
SessionRepository
某些 implementations 可能会选择同时实现。
例如,Spring Session 的 Apache Geode 支持实现了 .SessionRepository
FindByIndexNameSessionRepository
FindByIndexNameSessionRepository
这添加了一个方法来查找特定用户的所有会话。
这是通过确保带有 name 的 session 属性填充用户名来完成的。开发人员有责任确保填充该属性,因为
Spring Session 不知道正在使用的身份验证机制。FindByIndexNameSessionRepository
FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME
的一些 implementation will 提供钩子来自动索引其他 session 属性。
例如,许多实现将自动确保当前的 Spring Security 用户名使用
索引名称 . |
3.12. 启用 SpringHttpSession
可以将注释添加到任何类中,以将 Bean 公开为名为“springSessionRepositoryFilter”的 Spring 容器中的 Bean。@EnableSpringHttpSession
@Configuration
SessionRepositoryFilter
为了利用 Comments,必须提供单个 bean。SessionRepository
3.13. 启用 GemFireHttpSession
可以将注释添加到任何类中,以代替注释,以在 Spring 容器中将 bean 公开为名为
“springSessionRepositoryFilter”,并将 Apache Geode 定位为管理状态的提供程序。@EnableGemFireHttpSession
@Configuration
@EnableSpringHttpSession
SessionRepositoryFilter
javax.servlet.http.HttpSession
使用 annotation 时,额外的配置是开箱即用的,这也
提供了名为 的接口的 Apache Geode 特定实现。@EnableGemFireHttpSession
SessionRepository
GemFireOperationsSessionRepository
3.14. GemFireOperationsSessionRepository
GemFireOperationsSessionRepository
是使用 Spring Session 实现的
适用于 Apache Geode 的 s_ .SessionRepository
GemFireOperationsSessionRepository
在 Web 环境中,此存储库与 .SessionRepositoryFilter
此实现支持 ,并通过 .SessionCreatedEvents
SessionDeletedEvents
SessionDestroyedEvents
SessionEventHttpSessionListenerAdapter
3.14.1. 在 Apache Geode 中使用索引
虽然有关正确定义对 Apache Geode 性能有积极影响的索引的最佳实践 超出了本文档的范围,重要的是要认识到 Spring Session for Apache Geode 会创建 并使用 Indexes 高效地查询和查找 Sessions。
Spring Session for Apache Geode 在主体名称上创建 1 个哈希类型的索引。有两个
用于查找 Principal Name 的不同内置策略。第一个策略是 Session 的值
属性将被索引到相同的
索引名称。FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME
例如:
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_NAME
例如,如果您使用的是 Spring Security,则可以使用以下方法查找当前用户的会话:
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 中使用自定义索引
这使开发人员能够使用编程方式查询和查找所有会话
有效地使用给定的主体名称。GemFireOperationsSessionRepository
此外,Spring Session for Apache Geode 将在实现 Session 的
Map 类型属性(即在任何任意 Session 属性上),当开发人员标识 1 个或多个
命名的 Session 属性,这些属性应由 Apache Geode 编制索引。attributes
可以使用 Comments 上的属性指定要索引的 Sessions 属性。当开发人员希望启用 Spring Session 对 backed by 的支持时,将这个注解添加到他们的 Spring 应用程序类中
Apache Geode 的 Apache。indexableSessionAttributes
@EnableGemFireHttpSession
@Configuration
HttpSession
String indexName = "name1";
session.setAttribute(indexName, indexValue);
Map<String, Session> idToSessions =
this.sessionRepository.findByIndexNameAndIndexValue(indexName, indexValue);
只有在 annotation 的属性中标识的 Session 属性名称才会定义 Index。不会为所有其他 Session 属性编制索引。@EnableGemFireHttpSession indexableSessionAttributes |
但是,有一个问题。存储在可索引 Session 属性中的任何值都必须实现该接口。如果这些对象值未实现 ,则 Apache Geode
将在启动时引发错误,当为具有持久 Session 数据的区域定义 Index 时,或者尝试
在运行时进行,以便为可索引的 Session 属性分配一个不是的值,并保存 Session
到 Apache Geode。java.lang.Comparable<T>
Comparable
Comparable
任何未编制索引的 Session 属性都可以存储非 - 值。Comparable |
要了解有关 Apache Geode 基于范围的索引的更多信息,请参阅在映射字段上创建索引。
要了解有关 Apache Geode 索引的一般信息,请参阅使用索引。