国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發(fā) > Java > 正文

spring boot整合redis實(shí)現(xiàn)shiro的分布式session共享的方法

2024-07-13 10:17:22
字體:
供稿:網(wǎng)友

我們知道,shiro是通過SessionManager來管理Session的,而對于Session的操作則是通過SessionDao來實(shí)現(xiàn)的,默認(rèn)的情況下,shiro實(shí)現(xiàn)了兩種SessionDao,分別為CachingSessionDAO和MemorySessionDAO,當(dāng)我們使用EhCache緩存時(shí),則是使用的CachingSessionDAO,不適用緩存的情況下,就會(huì)選擇基于內(nèi)存的SessionDao.所以,如果我們想實(shí)現(xiàn)基于Redis的分布式Session共享,重點(diǎn)在于重寫SessionManager中的SessionDao。我們的重寫代碼如下:

package com.chhliu.springboot.shiro.cache; import java.io.Serializable; import java.util.Collection; import java.util.concurrent.TimeUnit; import org.apache.shiro.session.Session; import org.apache.shiro.session.UnknownSessionException; import org.apache.shiro.session.mgt.eis.AbstractSessionDAO; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Service;  @Service @SuppressWarnings({ "rawtypes", "unchecked" }) public class RedisSessionDao extends AbstractSessionDAO {    // Session超時(shí)時(shí)間,單位為毫秒   private long expireTime = 120000;    @Autowired   private RedisTemplate redisTemplate;// Redis操作類,對這個(gè)使用不熟悉的,可以參考前面的博客    public RedisSessionDao() {     super();   }    public RedisSessionDao(long expireTime, RedisTemplate redisTemplate) {     super();     this.expireTime = expireTime;     this.redisTemplate = redisTemplate;   }    @Override // 更新session   public void update(Session session) throws UnknownSessionException {     System.out.println("===============update================");     if (session == null || session.getId() == null) {       return;     }     session.setTimeout(expireTime);     redisTemplate.opsForValue().set(session.getId(), session, expireTime, TimeUnit.MILLISECONDS);   }    @Override // 刪除session   public void delete(Session session) {     System.out.println("===============delete================");     if (null == session) {       return;     }     redisTemplate.opsForValue().getOperations().delete(session.getId());   }    @Override// 獲取活躍的session,可以用來統(tǒng)計(jì)在線人數(shù),如果要實(shí)現(xiàn)這個(gè)功能,可以在將session加入redis時(shí)指定一個(gè)session前綴,統(tǒng)計(jì)的時(shí)候則使用keys("session-prefix*")的方式來模糊查找redis中所有的session集合   public Collection<Session> getActiveSessions() {     System.out.println("==============getActiveSessions=================");     return redisTemplate.keys("*");   }    @Override// 加入session   protected Serializable doCreate(Session session) {     System.out.println("===============doCreate================");     Serializable sessionId = this.generateSessionId(session);     this.assignSessionId(session, sessionId);      redisTemplate.opsForValue().set(session.getId(), session, expireTime, TimeUnit.MILLISECONDS);     return sessionId;   }    @Override// 讀取session   protected Session doReadSession(Serializable sessionId) {     System.out.println("==============doReadSession=================");     if (sessionId == null) {       return null;     }     return (Session) redisTemplate.opsForValue().get(sessionId);   }    public long getExpireTime() {     return expireTime;   }    public void setExpireTime(long expireTime) {     this.expireTime = expireTime;   }    public RedisTemplate getRedisTemplate() {     return redisTemplate;   }    public void setRedisTemplate(RedisTemplate redisTemplate) {     this.redisTemplate = redisTemplate;   } } 

SessionDao實(shí)現(xiàn)完了之后,我們就需要將SessionDao加入SessionManager中了,代碼如下:

 @Bean   public DefaultWebSessionManager configWebSessionManager(){     DefaultWebSessionManager manager = new DefaultWebSessionManager();     manager.setCacheManager(cacheManager);// 加入緩存管理器     manager.setSessionDAO(sessionDao);// 設(shè)置SessionDao     manager.setDeleteInvalidSessions(true);// 刪除過期的session     manager.setGlobalSessionTimeout(sessionDao.getExpireTime());// 設(shè)置全局session超時(shí)時(shí)間     manager.setSessionValidationSchedulerEnabled(true);// 是否定時(shí)檢查session          return manager;   } 

最后一步就是將SessionManager配置到SecurityManager中了

@Bean   public SecurityManager securityManager(DefaultWebSessionManager webSessionManager) {     DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();     // 設(shè)置realm.     securityManager.setRealm(myShiroRealm());      // 注入緩存管理器;     securityManager.setCacheManager(cacheManager);// 這個(gè)如果執(zhí)行多次,也是同樣的一個(gè)對象;          // session管理器     securityManager.setSessionManager(webSessionManager);          //注入記住我管理器;     securityManager.setRememberMeManager(rememberMeManager());     return securityManager;   } 

測試結(jié)果如下:

==============doReadSession================= 
==============doReadSession================= 
==============doReadSession================= 
==============doReadSession================= 
==============doReadSession================= 
==============doReadSession================= 
==============doReadSession================= 
==============doReadSession================= 
==============doReadSession================= 
==============doReadSession================= 
==============doReadSession================= 
==============doReadSession================= 
===============update================ 
==============doReadSession================= 
==============doReadSession================= 
===============update================ 
==============doReadSession================= 
==============doReadSession================= 
==============doReadSession================= 
權(quán)限配置-->MyShiroRealm.doGetAuthorizationInfo() 
==============doReadSession================= 

我們會(huì)發(fā)現(xiàn),當(dāng)一個(gè)頁面中存在多個(gè)資源的時(shí)候,會(huì)不停的調(diào)用doReadSession,update方法來讀取和更新session,目前這個(gè)問題還沒有想到比較好的解決方案。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持VeVb武林網(wǎng)。


注:相關(guān)教程知識閱讀請移步到JAVA教程頻道。
發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 鄂伦春自治旗| 镇坪县| 永嘉县| 清水县| 蓝山县| 景洪市| 迁西县| 江源县| 青海省| 淳安县| 武威市| 达日县| 定日县| 宁陕县| 襄樊市| 佛冈县| 乐陵市| 安阳市| 镇赉县| 天全县| 通州市| 本溪| 双牌县| 定州市| 博乐市| 盈江县| 禄丰县| 凤山市| 锦州市| 许昌县| 旌德县| 昌邑市| 中江县| 瓮安县| 简阳市| 安国市| 句容市| 云浮市| 米林县| 清水河县| 将乐县|