spring-boot 结合redis做session共享
环境
spring-boot 2.13
引入依赖
此时应配置完成redis
spring-boot集成redis
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
session共享配置
appicaion.yml
server:
port: 8080
spring:
session:
store-type: redis
SessionConfig
//maxInactiveIntervalInSeconds session 过期时间
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 1800)
public class SessionConfig{
}
写点测试方法。Controller
//获取当前启动的端口号
@Value("${server.port}")
private String port;
@GetMapping("/hello")
public String hello(HttpServletRequest request){
HttpSession session = request.getSession();
session.setAttribute("hello","spring data session redis");
return "session redis : " + port;
}
@GetMapping("/getSession")
public String getSession(HttpServletRequest request){
HttpSession session = request.getSession();
String v = (String)session.getAttribute("hello");
return v + " : " + port;
}
简单模拟session共享
nginx 配置
nginx 监听了8080和8081两个端口,www.test.com 配置到了hosts中。
http{
upstream myserver{
server localhost:8080;
server localhost:8081;
}
server{
server_name www.test.com;
location /demo/{
proxy_pass http://myserver/demo/;
}
}
}
host设置
127.0.0.1 www.test.com
测试
session-1.png session-2.png将spring-boot 分别打包为端口为8080、8081两个jar包。并且分别启动。
启动nginx
如下图所示,不断请求接口,请求会通过nginx分发到 8080、8081 程序中。并且session 也已经存储到redis中。
spring-boot 结合redis做session 监听
前文中session 共享已经实现了。 但是此时发现session监听只能监听到session的创建,session的销毁则监听不到了。 经过查询spring-session文档 发现session的监听则需要使用
SessionEventHttpSessionListenerAdapter
//session 监听类
public class DemoHttpSessionListener implements HttpSessionListener {
public void sessionCreated(HttpSessionEvent event) {
System.out.println("创建Session");
}
@Override
public void sessionDestroyed(HttpSessionEvent event) {
System.out.println("销毁Session");
}
}
代码更新
//session 配置类增加监听
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 1800)
public class SessionConfig{
@Bean
public SessionEventHttpSessionListenerAdapter sessionEventHttpSessionListenerAdapter(){
List<HttpSessionListener> list = new ArrayList<>();
list.add(new DemoHttpSessionListener());
this.setHttpSessionListeners(list);
return new SessionEventHttpSessionListenerAdapter(list);
}
}
报错啦
更新完成代码后,启动项目发现报如下错误。
Consider renaming one of the beans or enabling overriding by setting spring.main.allow-bean-definition-overriding=true
看错误提示是让我开启
spring.main.allow-bean-definition-overriding=true
这个配置,开启之后确实好了。但是,为啥嘞???
经过一番查询之后,发现自从spring-boot 2.1.0之后的版本,禁用了bean名称覆盖,开启之后就好了。
我本着spring官方比我牛逼的想法。决定尊重spring 的决定。
session-4.png session-5.png查看源码发现
session-3.pngSpringHttpSessionConfiguration
中注入了SessionEventHttpSessionListenerAdapter
。
@EnableRedisHttpSession
引入了RedisHttpSessionConfiguration
,而RedisHttpSessionConfiguration
继承了SpringHttpSessionConfiguration
看完这个关系之后,发现
SessionEventHttpSessionListenerAdapter
注入的时候添加了Session监听。
再次更新代码
@Configuration
public class SessionConfig extends RedisHttpSessionConfiguration {
public SessionConfig(){
List<HttpSessionListener> list = new ArrayList<>();
list.add(new DemoHttpSessionListener());
this.setHttpSessionListeners(list);
this.setMaxInactiveIntervalInSeconds(60);
}
// 添加session 监听
@Override
public void setHttpSessionListeners(List<HttpSessionListener> listeners) {
super.setHttpSessionListeners(listeners);
}
//设置session过期时间
@Override
public void setMaxInactiveIntervalInSeconds(int maxInactiveIntervalInSeconds) {
super.setMaxInactiveIntervalInSeconds(maxInactiveIntervalInSeconds);
}
}
添加测试代码
@GetMapping("/destroySession")
public String destroySession(HttpSession session){
session.invalidate();
return "success";
}
启动项目,请求接口。控制台输出结果。已经可以监听到session销毁。
网友评论