2步轻松搞定SpringBoot2.x分布式session共享,极少配置
优质文章,第一时间送达
作者 :日常打BUG
转载自 :blog.csdn.net/qq_38023253/article/details/90581455
集成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
@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实例增加物理连接
集成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设置还没生效,原因还在寻找中。
@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:[email protected]}");
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中
实验效果:
sessionId一致,且成功获取了session中对象,不同端口间session实现共享
开箱即用的便利
注释掉第二步集成spring-session-Redis后的配置,只导入jar包进行测试,其session还是存入了Redis中,结果如上面二图所示,跟增加配置后的效果一致
将引入spring-session-Redis jar包也注释掉 进行测试,也就是回到没集成session-redis前,如下图所示,此时session不再存放在Redis中,且不同端口号之间的session不互通,相同端口session也会有过期时间。
结果:相同端口之间的session共享,不同端口间session隔离
出现上下两种情况是springboot开箱即用的效果,引入jar包后无需配置即可使用。
有热门推荐👇
想充电就关注程序员闪充宝