第一步:添加Spring Session和 redis的相关依赖

    1. <parent>
    2. <groupId>org.springframework.boot</groupId>
    3. <artifactId>spring-boot-starter-parent</artifactId>
    4. <version>2.4.1</version>
    5. </parent>
    6. <dependencies>
    7. <dependency>
    8. <groupId>org.springframework.boot</groupId>
    9. <artifactId>spring-boot-starter-web</artifactId>
    10. </dependency>
    11. <dependency>
    12. <groupId>org.springframework.session</groupId>
    13. <artifactId>spring-session-data-redis</artifactId>
    14. </dependency>
    15. <dependency>
    16. <groupId>org.springframework.boot</groupId>
    17. <artifactId>spring-boot-starter-data-redis</artifactId>
    18. </dependency>
    19. <dependency>
    20. <groupId>org.apache.commons</groupId>
    21. <artifactId>commons-pool2</artifactId>
    22. <version>2.11.1</version>
    23. </dependency>
    24. </dependencies>

    第二步:配置redis相关信息

    1. spring:
    2. redis:
    3. # redis 服务器地址
    4. host: localhost
    5. # redis 端口号
    6. port: 6379
    7. # redis 密码
    8. password:
    9. # session 使用redis存储
    10. session: store-type:redis

    第三步:项目中使用session

    1. @SpringBootApplication
    2. @EnableRedisHttpSession
    3. public class SpringsessionApplication {
    4. public static void main(String[] args) {
    5. SpringApplication.run(SpringsessionApplication.class, args);
    6. }
    7. }
    1. @RestController
    2. @RequestMapping("/session")
    3. public class SessionController {
    4. /**
    5. * 设置session
    6. * @param request
    7. * @param attributes
    8. * @return
    9. */
    10. @PostMapping("/set")
    11. public Map<String,Object> setSession(HttpServletRequest request, @RequestParam("attributes")String attributes){
    12. request.getSession().setAttribute("attributes",attributes);
    13. Map<String,Object> map = new HashMap<String,Object>();
    14. map.put("SessionID:",request.getSession().getId());
    15. return map;
    16. }
    17. /**
    18. * 获取session
    19. * @param request
    20. * @return
    21. */
    22. @GetMapping("/get")
    23. public String getSession(HttpServletRequest request){
    24. String attributes = (String) request.getSession().getAttribute("attributes");
    25. return attributes;
    26. }
    27. }

    image.png
    redis中每个session存储了三条信息。
    image.png

    • 第一个存储这个Session的id,是一个Set类型的Redis数据结构。这个k中的最后的1439245080000值是一个时间戳,根据这个Session过期时刻滚动至下一分钟而计算得出。
    • 第二个用来存储Session的详细信息,包括Session的过期时间间隔、最近的访问时间、attributes等等。这个k的过期时间为Session的最大过期时间 + 5分钟。如果默认的最大过期时间为30分钟,则这个k的过期时间为35分钟。
    • 第三个用来表示Session在Redis中的过期,这个k-v不存储任何有用数据,只是表示Session过期而设置。这个k在Redis中的过期时间即为Session的过期时间间隔。处理一个session为什么要存储三条数据,而不是一条呢!对于session的实现,需要监听它的创建、过期等事件,redis可以监听某个key的变化,当key发生变化时,可以快速做出相应的处理。

    但是Redis中带有过期的key有两种方式:
    当访问时发现其过期Redis后台逐步查找过期键当访问时发现其过期,会产生过期事件,但是无法保证key的过期时间抵达后立即生成过期事件。
    spring-session为了能够及时的产生Session的过期时的过期事件,所以增加了:

    spring:session:sessions:expires:726de8fc-c045-481a-986d-f7c4c5851a67spring:session:expirations:1620393360000

    spring-session中有个定时任务,每个整分钟都会查询相应的spring:session:expirations:整分钟的时间戳中的过期SessionId,然后再访问一次这个SessionId,即spring:session:sessions:expires:SessionId,以便能够让Redis及时的产生key过期事件——即Session过期事件。