欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

SpringSession會話管理之Redis與JDBC存儲實(shí)現(xiàn)方式

 更新時(shí)間:2025年04月15日 10:15:42   作者:程序媛學(xué)姐  
本文將詳細(xì)介紹Spring Session的核心概念、特性以及如何使用Redis和JDBC來實(shí)現(xiàn)會話存儲,幫助開發(fā)者構(gòu)建更加健壯和可擴(kuò)展的應(yīng)用系統(tǒng),希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

引言

在分布式應(yīng)用架構(gòu)中,會話管理是一個(gè)關(guān)鍵挑戰(zhàn)。傳統(tǒng)的容器內(nèi)存儲會話的方法在多個(gè)服務(wù)實(shí)例間難以共享,導(dǎo)致用戶在不同服務(wù)器間切換時(shí)會話丟失。

Spring Session提供了一種創(chuàng)建和管理用戶會話的標(biāo)準(zhǔn)方法,使會話可以脫離應(yīng)用服務(wù)器的限制,實(shí)現(xiàn)跨多個(gè)服務(wù)實(shí)例的會話共享。

一、Spring Session基本概念

Spring Session是Spring生態(tài)系統(tǒng)中的一個(gè)項(xiàng)目,它提供了一套API和實(shí)現(xiàn)來管理用戶會話。其核心優(yōu)勢在于能夠?qū)挻鎯膽?yīng)用服務(wù)器剝離,放置到外部存儲系統(tǒng)中,從而實(shí)現(xiàn)會話的跨應(yīng)用共享和持久化。

Spring Session的主要特性包括:

  • 透明集成:對現(xiàn)有應(yīng)用代碼幾乎無侵入性
  • 多種存儲方式:支持Redis、JDBC、MongoDB等多種后端存儲
  • 安全支持:與Spring Security無縫集成
  • REST API支持:提供了基于請求頭的會話傳遞機(jī)制,適用于RESTful應(yīng)用
  • WebSocket支持:保證WebSocket通信中會話的連續(xù)性

要在項(xiàng)目中使用Spring Session,首先需要添加相應(yīng)的依賴。以Spring Boot項(xiàng)目為例,根據(jù)存儲類型選擇相應(yīng)的依賴:

<!-- Redis存儲 -->
<dependency>
    <groupId>org.springframework.session</groupId>
    <artifactId>spring-session-data-redis</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

<!-- 或者JDBC存儲 -->
<dependency>
    <groupId>org.springframework.session</groupId>
    <artifactId>spring-session-jdbc</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>

二、Redis實(shí)現(xiàn)會話存儲

Redis是一個(gè)高性能的鍵值存儲系統(tǒng),非常適合用于存儲會話數(shù)據(jù)。

使用Redis存儲會話具有低延遲、高可用性和水平擴(kuò)展能力,是分布式系統(tǒng)中會話管理的理想選擇。

2.1 配置Redis會話存儲

在Spring Boot應(yīng)用中,配置Redis會話存儲非常簡單:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;

@Configuration
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 1800) // 會話過期時(shí)間:30分鐘
public class RedisSessionConfig {
    
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(connectionFactory);
        return template;
    }
}

@EnableRedisHttpSession注解自動配置了一個(gè)RedisIndexedSessionRepository,它負(fù)責(zé)會話的創(chuàng)建、保存、刪除和過期處理。

在application.properties或application.yml中配置Redis連接信息:

# Redis服務(wù)器連接配置
spring.redis.host=localhost
spring.redis.port=6379
# 如果需要密碼認(rèn)證
spring.redis.password=your-password

# Spring Session配置
spring.session.store-type=redis
spring.session.redis.namespace=spring:session

2.2 Redis會話示例

Redis會話存儲的工作機(jī)制是透明的,開發(fā)者可以像使用普通HttpSession一樣使用它:

import javax.servlet.http.HttpSession;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class SessionController {
    
    @GetMapping("/session/set")
    public String setSessionAttribute(HttpSession session) {
        session.setAttribute("username", "john.doe");
        session.setAttribute("role", "admin");
        return "Session attributes set successfully";
    }
    
    @GetMapping("/session/get")
    public String getSessionAttribute(HttpSession session) {
        String username = (String) session.getAttribute("username");
        String role = (String) session.getAttribute("role");
        return "Username: " + username + ", Role: " + role;
    }
}

在后臺,Spring Session攔截了HttpSession的操作,將會話數(shù)據(jù)存儲在Redis中。Redis存儲會話的數(shù)據(jù)結(jié)構(gòu)如下:

  • spring:session:sessions:<sessionId> - 存儲會話本身
  • spring:session:sessions:expires:<sessionId> - 存儲會話的過期信息
  • spring:session:expirations:<expireTime> - 按過期時(shí)間索引的會話列表

三、JDBC實(shí)現(xiàn)會話存儲

對于已經(jīng)使用關(guān)系型數(shù)據(jù)庫的應(yīng)用,JDBC會話存儲是一個(gè)不錯(cuò)的選擇。它利用現(xiàn)有的數(shù)據(jù)庫基礎(chǔ)設(shè)施,簡化了系統(tǒng)架構(gòu)和運(yùn)維復(fù)雜度。

3.1 配置JDBC會話存儲

在Spring Boot應(yīng)用中,配置JDBC會話存儲同樣簡單:

import org.springframework.context.annotation.Configuration;
import org.springframework.session.jdbc.config.annotation.web.http.EnableJdbcHttpSession;

@Configuration
@EnableJdbcHttpSession(maxInactiveIntervalInSeconds = 1800, tableName = "SPRING_SESSION")
public class JdbcSessionConfig {
    // JDBC會話存儲不需要額外的Bean定義
}

@EnableJdbcHttpSession注解配置了一個(gè)JdbcIndexedSessionRepository,它使用JDBC來存儲和檢索會話數(shù)據(jù)。

在application.properties中配置數(shù)據(jù)源和會話存儲類型:

# 數(shù)據(jù)源配置
spring.datasource.url=jdbc:mysql://localhost:3306/session_db
spring.datasource.username=root
spring.datasource.password=password
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

# Spring Session配置
spring.session.store-type=jdbc
spring.session.jdbc.initialize-schema=always

Spring Session會自動創(chuàng)建所需的數(shù)據(jù)庫表。默認(rèn)情況下,會創(chuàng)建以下表:

  • SPRING_SESSION - 存儲會話元數(shù)據(jù)
  • SPRING_SESSION_ATTRIBUTES - 存儲會話屬性

3.2 JDBC會話表結(jié)構(gòu)

JDBC會話存儲使用的表結(jié)構(gòu)如下:

CREATE TABLE SPRING_SESSION (
  PRIMARY_ID CHAR(36) NOT NULL,
  SESSION_ID CHAR(36) NOT NULL,
  CREATION_TIME BIGINT NOT NULL,
  LAST_ACCESS_TIME BIGINT NOT NULL,
  MAX_INACTIVE_INTERVAL INT NOT NULL,
  EXPIRY_TIME BIGINT NOT NULL,
  PRINCIPAL_NAME VARCHAR(100),
  CONSTRAINT SPRING_SESSION_PK PRIMARY KEY (PRIMARY_ID)
);

CREATE TABLE SPRING_SESSION_ATTRIBUTES (
  SESSION_PRIMARY_ID CHAR(36) NOT NULL,
  ATTRIBUTE_NAME VARCHAR(200) NOT NULL,
  ATTRIBUTE_BYTES BLOB NOT NULL,
  CONSTRAINT SPRING_SESSION_ATTRIBUTES_PK PRIMARY KEY (SESSION_PRIMARY_ID, ATTRIBUTE_NAME),
  CONSTRAINT SPRING_SESSION_ATTRIBUTES_FK FOREIGN KEY (SESSION_PRIMARY_ID) REFERENCES SPRING_SESSION(PRIMARY_ID) ON DELETE CASCADE
);

這些表存儲了會話ID、創(chuàng)建時(shí)間、最后訪問時(shí)間、過期時(shí)間以及所有會話屬性。

四、高級特性與最佳實(shí)踐

4.1 自定義會話序列化

默認(rèn)情況下,Spring Session使用JDK序列化來存儲會話屬性。為了提高性能和兼容性,可以自定義序列化機(jī)制:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;

@Configuration
@EnableRedisHttpSession
public class RedisSessionConfig {
    
    @Bean
    public RedisSerializer<Object> springSessionDefaultRedisSerializer() {
        return new GenericJackson2JsonRedisSerializer();
    }
}

對于JDBC存儲,可以實(shí)現(xiàn)SessionConverter接口來自定義序列化:

@Configuration
@EnableJdbcHttpSession
public class JdbcSessionConfig {
    
    @Bean
    public SessionConverter sessionConverter() {
        return new JacksonSessionConverter();
    }
}

4.2 會話事件監(jiān)聽

Spring Session提供了一系列事件,允許開發(fā)者在會話生命周期的不同階段執(zhí)行自定義邏輯:

import org.springframework.context.event.EventListener;
import org.springframework.session.events.*;
import org.springframework.stereotype.Component;

@Component
public class SessionEventListener {
    
    @EventListener
    public void onCreation(SessionCreatedEvent event) {
        System.out.println("Session created: " + event.getSessionId());
    }
    
    @EventListener
    public void onExpiration(SessionExpiredEvent event) {
        System.out.println("Session expired: " + event.getSessionId());
    }
    
    @EventListener
    public void onDeletion(SessionDeletedEvent event) {
        System.out.println("Session deleted: " + event.getSessionId());
    }
}

4.3 多瀏覽器會話支持

Spring Session支持在同一用戶的不同瀏覽器或設(shè)備上維護(hù)獨(dú)立的會話:

import org.springframework.context.annotation.Bean;
import org.springframework.session.web.http.CookieSerializer;
import org.springframework.session.web.http.DefaultCookieSerializer;

@Configuration
public class SessionConfig {
    
    @Bean
    public CookieSerializer cookieSerializer() {
        DefaultCookieSerializer serializer = new DefaultCookieSerializer();
        serializer.setCookieName("SESSION");
        serializer.setCookiePath("/");
        serializer.setDomainNamePattern("^.+?\\.(\\w+\\.[a-z]+)$");
        return serializer;
    }
}

五、性能與安全考慮

在生產(chǎn)環(huán)境中使用Spring Session時(shí),需要考慮以下性能和安全因素:

  • Redis持久化:配置Redis的持久化策略(AOF或RDB),確保在Redis服務(wù)重啟時(shí)不會丟失會話數(shù)據(jù)。
  • 連接池管理:為Redis或數(shù)據(jù)庫配置適當(dāng)?shù)倪B接池,避免連接資源耗盡。
  • 會話清理:定期清理過期的會話數(shù)據(jù),特別是使用JDBC存儲時(shí)。
  • 會話超時(shí):根據(jù)應(yīng)用安全需求設(shè)置合理的會話超時(shí)時(shí)間。
  • Cookie安全:配置會話Cookie的安全屬性:
@Bean
public CookieSerializer cookieSerializer() {
    DefaultCookieSerializer serializer = new DefaultCookieSerializer();
    serializer.setUseSecureCookie(true); // 僅在HTTPS連接中傳輸
    serializer.setUseHttpOnlyCookie(true); // 防止JavaScript訪問
    serializer.setSameSite("Strict"); // 防止CSRF攻擊
    return serializer;
}

總結(jié)

Spring Session為分布式應(yīng)用提供了一個(gè)強(qiáng)大而靈活的會話管理解決方案。通過將會話數(shù)據(jù)從應(yīng)用服務(wù)器轉(zhuǎn)移到Redis或關(guān)系型數(shù)據(jù)庫等外部存儲中,實(shí)現(xiàn)了會話的跨服務(wù)實(shí)例共享,為構(gòu)建可擴(kuò)展的分布式系統(tǒng)奠定了基礎(chǔ)。

Redis存儲方案提供了高性能和高可用性,適合對響應(yīng)時(shí)間要求較高的應(yīng)用;而JDBC存儲方案則充分利用了現(xiàn)有的數(shù)據(jù)庫基礎(chǔ)設(shè)施,適合已經(jīng)大量使用關(guān)系型數(shù)據(jù)庫的項(xiàng)目。

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 基于Springboot+Netty實(shí)現(xiàn)rpc的方法 附demo

    基于Springboot+Netty實(shí)現(xiàn)rpc的方法 附demo

    這篇文章主要介紹了基于Springboot+Netty實(shí)現(xiàn)rpc功能,在父項(xiàng)目中引入相關(guān)依賴結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-02-02
  • 深入了解Java8中的時(shí)區(qū)日期時(shí)間

    深入了解Java8中的時(shí)區(qū)日期時(shí)間

    Java?在?java.time?包中也提供了幾個(gè)類用于處理需要關(guān)注時(shí)區(qū)的日期時(shí)間?API,本文將通過簡單的示例講講它們的用法,需要的可以參考一下
    2023-04-04
  • SpringBoot詳解執(zhí)行過程

    SpringBoot詳解執(zhí)行過程

    這篇文章主要介紹了SpringBoot的執(zhí)行過程原理,Spring Boot是由Pivotal團(tuán)隊(duì)提供的全新框架,其設(shè)計(jì)目的是用來簡化新Spring應(yīng)用的初始搭建以及開發(fā)過程,文中通過實(shí)例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2022-07-07
  • Spring Security+Spring Data Jpa如何進(jìn)行安全管理

    Spring Security+Spring Data Jpa如何進(jìn)行安全管理

    這篇文章主要介紹了Spring Security+Spring Data Jpa如何進(jìn)行安全管理,幫助大家更好的理解和學(xué)習(xí)Spring Security框架,感興趣的朋友可以了解下
    2020-09-09
  • Java中BIO、NIO、AIO的理解

    Java中BIO、NIO、AIO的理解

    這篇文章主要為大家詳細(xì)介紹了Java中BIO、NIO、AIO的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-12-12
  • Java有序的Map LinkedHashMap用法詳解

    Java有序的Map LinkedHashMap用法詳解

    LinkedHashMap是Java提供的一個(gè)集合類,它繼承自HashMap,并在HashMap基礎(chǔ)上維護(hù)一條雙向鏈表,本文給大家介紹java 有序的Map LinkedHashMap簡介,感興趣的朋友一起看看吧
    2024-01-01
  • 關(guān)于Java中Bean的作用域詳解

    關(guān)于Java中Bean的作用域詳解

    這篇文章主要介紹了關(guān)于Java中Bean的作用域詳解,限定程序中變量的可?范圍叫做作?域,或者說在源代碼中定義變量的某個(gè)區(qū)域就叫做作?域,需要的朋友可以參考下
    2023-08-08
  • SpringDataJPA之Specification復(fù)雜查詢實(shí)戰(zhàn)

    SpringDataJPA之Specification復(fù)雜查詢實(shí)戰(zhàn)

    這篇文章主要介紹了SpringDataJPA之Specification復(fù)雜查詢實(shí)戰(zhàn),具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • JUC并發(fā)編程LinkedBlockingQueue隊(duì)列深入分析源碼

    JUC并發(fā)編程LinkedBlockingQueue隊(duì)列深入分析源碼

    LinkedBlockingQueue 是一個(gè)可選有界阻塞隊(duì)列,這篇文章主要為大家詳細(xì)介紹了Java中LinkedBlockingQueue的實(shí)現(xiàn)原理與適用場景,感興趣的可以了解一下
    2023-04-04
  • springboot 獲取工具類bean過程詳解

    springboot 獲取工具類bean過程詳解

    這篇文章主要介紹了springboot 獲取工具類bean過程詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-09-09

最新評論