Spring Session使用及源码解析
参照:
http://blog.csdn.net/wojiaolinaaa/article/details/62424642
总结点spring session的一些知识点:
spring通过过滤器,拦截相应的请求。过滤器必须配置在所有过滤器的第一位。这个过滤器负责将本地session与保存在redis中的session数据同步。
调用getSession方法时,会通过sessionid从redis中取出对应的session二进制数据,然后反序列化成session对象。
filter结束时,在finally中,将本次修改的session序列化后提交到redis。
最近的使用过程中发现spring-session的几个问题
1. 在提交session到redis时,spring提交的是修改的session数据,未修改的并未提交。那怎么判断里面的数据有没有修改呢?session用delta记录了修改的内容,只有在主动调用removeAttribute和setAttribute方法时,才会把键值对放入delta中。这就会导致一个问题:我先通过getAttribute获取session里存的对象,然后直接修改对象的数据,但并没有重新setAttribute方法(直接通过地址修改数据,没必要再setAttribute的),因为没有调用setAttribute方法,spring是感知不到session变化的。这就导致修改的数据,在下一个请求中去获取时,还是获取的旧数据的问题。
解决办法是,spring在提交delta中的数据前,将现有的session与getsession时拿到的数据做对比,把equals为false的对象放入delta中一并提交。
2.单机情况下,session中存了大量的缓存数据,使用spring session后,这些缓存数据都放入到了redis中,每去getsession时,都会从redis上通过sessionid取出该session全量的数据,如果一个请求中有多次用到getsession,就会取无意义的取多次,性能和耗时是一方面的问题。
getsession后,也会在本地创建大量的对象,每次getsession都会创建大量对象,对垃圾回收来说,是很恐怖的一件事,一个页面要多少个请求?一个请求要多少次getsession?想想