SpringBoot2.1.4快速整合session-redis实现分布式session共享,极少配置

    xiaoxiao2025-07-19  4

    SpringBoot2.1.4与redis、springsession

    集成redis集成spring-session-Redis实验效果: 开箱即用的便利

    集成redis

    1.引入jar包

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

    2.配置属性 在application.properties增加Redis服务的相关信息

    #################redis单服务基础配置################# spring.redis.database=0 spring.redis.host=127.0.0.1 spring.redis.password= spring.redis.port=6379

    3. RedisTemplate配置

    /** * RedisTemplate配置 */ @Bean public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory lettuceConnectionFactory) { // 设置序列化 Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>( Object.class); ObjectMapper om = new ObjectMapper(); om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); jackson2JsonRedisSerializer.setObjectMapper(om); // 配置redisTemplate RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>(); redisTemplate.setConnectionFactory(lettuceConnectionFactory); RedisSerializer<?> stringSerializer = new StringRedisSerializer(); redisTemplate.setKeySerializer(stringSerializer);// key序列化 redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);// value序列化 redisTemplate.setHashKeySerializer(stringSerializer);// Hash key序列化 redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);// Hash value序列化 redisTemplate.afterPropertiesSet(); return redisTemplate; }

    不配置RedisTemplate,也是可以自动注入StringRedisTemplate进行redis的读写操作,但是不能注入 RedisTemplate<K, V>对象,这里先配置了 RedisTemplate<String, Object>来操作redis

    4. 注入RedisTemplate,开始使用操作Redis

    @RequestMapping(path = "/redis" ) public class RedisController { @Autowired private StringRedisTemplate stringRedisTemplate; @Autowired private RedisTemplate<String, Object> redisTemplate; /** * stringRedisTemplate 传入对象 * @return */ @GetMapping("/test2") public UUser testRedis2() { UUser user = new UUser(); user.setUserName("test2"); user.setEmail("11费@QQ.com"); stringRedisTemplate.opsForValue().set("A2", JSONObject.toJSONString(user)); UUser stu1 = JSONObject.parseObject(stringRedisTemplate.opsForValue().get("A2"), UUser.class); return stu1; } /** * redisTemplate传入对象 * @return */ @GetMapping("/test1") public UUser testRedis1() { UUser user = new UUser(); user.setUserName("test1"); user.setEmail("11飞@163.com"); redisTemplate.opsForValue().set("A1", user); UUser stu1 = (UUser) redisTemplate.opsForValue().get("A1"); // redisTemplate.delete("A1"); return stu1; } }

    通过localhost:8080/redis/test1、localhost:8080/redis/test2来进行验证

    5.可配置连接池

    <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> </dependency>

    Jedis与Lettuce的区别: Jedis在实现上是直接连接的redis server,如果在多线程环境下是非线程安全的,这个时候只有使用连接池,为每个Jedis实例增加物理连接 Lettuce的连接是基于Netty的,连接实例(StatefulRedisConnection)可以在多个线程间并发访问,应为StatefulRedisConnection是线程安全的,所以一个连接实例(StatefulRedisConnection)就可以满足多线程环境下的并发访问,当然这个也是可伸缩的设计,一个连接实例不够的情况也可以按需增加连接实例。 springboot2.0后将之前的jedis已经改成Lettuce,默认使用Lettuce

    集成spring-session-Redis

    参考 https://blog.csdn.net/qq_35206261/article/details/82289066 1 引入jar包

    <dependency> <groupId>org.springframework.session</groupId> <artifactId>spring-session-data-redis</artifactId> </dependency>

    2 配置

    @Configuration @EnableRedisHttpSession(maxInactiveIntervalInSeconds = 1900) public class RedisSessionConfig { }

    application.properties增加

    spring.session.store-type=redis

    也可不进行配置,都有默认值,开箱即用。 这里的maxInactiveIntervalInSeconds设置还没生效,原因还在寻找中。 3 测试session共享

    @RestController @RequestMapping(path = "/redis" ) public class RedisController { /** * session测试 * @param request * @return */ @RequestMapping(value = "/session", method = RequestMethod.GET) public Map<String, String> addSession (HttpServletRequest request){ String sessionId = request.getSession().getId(); String requestURI = request.getRequestURI() + ":" + request.getServerPort(); // 向session中保存用户信息 key规则: user + "_" + uid request.getSession().setAttribute("user_1", "{uid:1,username:11@qq.com}"); Map<String, String> sessionInfoMap = new HashMap<>(2); sessionInfoMap.put("sessionId", sessionId); sessionInfoMap.put("requestURI", requestURI); return sessionInfoMap; } /** * session测试 * @param request * @return */ @RequestMapping(value = "/getSession", method = RequestMethod.GET) public Map<String, String> getSession (HttpServletRequest request){ String sessionId = request.getSession().getId(); String requestURI = request.getRequestURI() + ":" + request.getServerPort(); Map<String, String> sessionInfoMap = new HashMap<>(2); // 获取session中uid为1的用户的信息 String user_1 = (String) request.getSession().getAttribute("user_1"); sessionInfoMap.put("sessionId", sessionId); sessionInfoMap.put("requestURI", requestURI); sessionInfoMap.put("user_1", user_1); return sessionInfoMap; } }

    分别启动不同的端口号,使用浏览器、postman、rest client测试sessionID

    结果:使用同一工具,例如postman测试不同端口号请求,其sessionId值一致,并且能从一个端口获取另一个端口存在request中的user信息。session数据存放在redis中

    1.8080端口往session中放入对象 2.8081端口请求session中对象

    实验效果:

    sessionId一致,且成功获取了session中对象,不同端口间session实现共享

    开箱即用的便利

    注释掉第二步集成spring-session-Redis后的配置,只导入jar包进行测试,其session还是存入了Redis中,结果如上面二图所示,跟增加配置后的效果一致

    将引入spring-session-Redis jar包也注释掉 进行测试,也就是回到没集成session-redis前,如下图所示,此时session不再存放在Redis中,且不同端口号之间的session不互通,相同端口session也会有过期时间。

    1.8080往session中放入对象 2.8081读取session信息 3.8081再次读取session信息(刷新一次) 结果:相同端口之间的session共享,不同端口间session隔离 出现上下两种情况是springboot开箱即用的效果,引入jar包后无需配置即可使用。

    最新回复(0)