美文网首页
spring-boot 结合redis做session共享与监听

spring-boot 结合redis做session共享与监听

作者: EricDD | 来源:发表于2019-05-04 22:36 被阅读0次

    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
    

    测试

    将spring-boot 分别打包为端口为8080、8081两个jar包。并且分别启动。
    启动nginx
    如下图所示,不断请求接口,请求会通过nginx分发到 8080、8081 程序中。并且session 也已经存储到redis中。

    session-1.png session-2.png

    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 的决定。

    查看源码发现SpringHttpSessionConfiguration中注入了SessionEventHttpSessionListenerAdapter
    @EnableRedisHttpSession 引入了 RedisHttpSessionConfiguration,而RedisHttpSessionConfiguration 继承了 SpringHttpSessionConfiguration

    session-3.png
    session-4.png session-5.png

    看完这个关系之后,发现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销毁。

    相关文章

      网友评论

          本文标题:spring-boot 结合redis做session共享与监听

          本文链接:https://www.haomeiwen.com/subject/vgtqoqtx.html