spring-boot-2.0.3不一样系列之番外篇 - 自定义session管理,绝对有值得你看的地方 前言

 

前言

  还记得当初写spring-session实现分布式集群session的共享的时候,里面有说到利用filter和HttpServletRequestWrapper可以定制自己的getSession方法,实现对session的控制,从而将session存放到统一的位置进行存储,达到session共享的目的。但是具体是如何实现的没有提及,今天我们就从源码的角度来看看shiro的session共享实现。

  路漫漫其修远兮,吾将上下而求索!

  github:https://github.com/youzhibing

  码云(gitee):https://gitee.com/youzhibing

装饰模式

  进入正题之前我们先来看看另外一个内容,放松下心情。尽管目前房价依旧很高,但还是阻止不了大家对新房的渴望和买房的热情。如果大家买的是毛坯房,无疑还有一项艰巨的任务要面对,那就是装修。对新房进行装修并没有改变房屋用于居住的本质,但它可以让房子变得更漂亮、更温馨、更实用、更能满足居家的需求。在软件设计中,我们也有一种类似新房装修的技术可以对已有对象(新房)的功能进行扩展(装修),以获得更加符合用户需求的对象,使得对象具有更加强大的功能。这种技术对应于一种被称之为装饰模式的设计模式。

  装饰者模式又名包装模式,以对客户端透明的方式拓展对象的功能,能够让我们在不修改底层代码的情况下,给我们的对象赋予新的职责。是继承关系的一个替代方案。

  装饰模式类图

  装饰模式中的角色:    

    抽象构件(Component)角色:给出一个抽象接口,以规范准备接收附加责任的对象。
具体构件(ConcreteComponent)角色:定义一个将要接收附加责任的类。
装饰(Decorator)角色:持有一个构件(Component)对象的实例,并定义一个与抽象构件接口一致的接口。
具体装饰(ConcreteDecorator)角色:负责给构件对象“贴上”附加的责任

  源代码实现

    Component.java

 View Code

    ConcreteComponent.java

 View Code

    Decorator.java

 View Code

    ConcreteDecorator.java

 View Code

    更多详情在spring-boot-test下的com.lee.decorator包下

  jdk中的案例

    装饰模式在Java语言中的最著名的应用莫过于Java I/O标准库的设计了。由于Java I/O库需要很多性能的各种组合,如果这些性能都是用继承的方法实现的,那么每一种组合都需要一个类,这样就会造成大量性能重复的类出现。而如果采用装饰模式,那么类的数目就会大大减少,性能的重复也可以减至最少,因此装饰模式是Java I/O库的基本模式。

    由于Java I/O的对象众多,这里只画出InputStream的一部分

    我们来捋一捋这个类图在装饰模式中角色的对应

      抽象构件(Component)角色:InputStream,这是一个抽象类,为各种子类型提供统一的接口
具体构件(ConcreteComponent)角色:FileInputStream,实现了抽象构件角色所规定的接口
装饰(Decorator)角色:FilterInputStream,它实现了InputStream所规定的接口
具体装饰(ConcreteDecorator)角色:BufferedInputStream

自定义session管理

  我们先来看看一个请求的发起到响应的时序图

  Interceptor依赖具体的框架(当然我们也可以自己实现),不是Servlet的内容,暂且先将其抛开,那么相当于请求先经过Filter链,再到Servlet,然后servlet处理完之后,再经过Filter链返回给浏览器。

  此时我们要对session的获取进行定制,我们能怎么处理?两种选择,一是从Servlet入手,二是从Filter入手。那我们想一想,从Servlet入手可行吗?可行,只是可行性非常低,因为我们需要定制的东西就太多了,容器的那套Servlet规范实现我们都需要自己来实现了。如果从Filter入手,我们可以继续沿用容器的那套实现,并从中插入我们的定制内容,那么改动的内容就很少了。具体如何实现,我们一起往下看

  定制session管理

    servlet容器的session创建

      在实现我们自己的session管理之前,我们先来看看session在servlet容器中的创建。

      客户端第一次请求request.getSession()时,也就是说客户端的请求中服务端第一次调用request.getSession()时,服务器会创建了Session对象并保存在servlet容器的session集合中,同时生成一个Session id,并通过响应头的Set-Cookie命令,向客户端发送要求设置cookie的响应(cookie中设置Session id信息),客户端收到响应后,在客户端设置了一个JSESSIONID=XXXXXXX的cookie信息;接下来客户端每次向服务器发送请求时,请求头都会带上该cookie信息(包含Session id)

50000+
5万行代码练就真实本领
17年
创办于2008年老牌培训机构
1000+
合作企业
98%
就业率

联系我们

电话咨询

0532-85025005

扫码添加微信