最近項目中用到的Session共享場景:兩個獨立應用,希望實現DB層共享用戶,而且用戶只需要登錄一次。
分析:這種場合,不適用單點,因為用戶數據並不需要單獨在第三方應用管理,而且添加單點也會增加整個系統的復雜度
兩種實現思路:Session數據存在DB中或者緩存Ehcache中
決策:考慮到查詢效率問題,使用緩存機制。
步驟如下:(已經過實際項目檢驗,如您遇到問題,請在評論中回復)
1. ehcache.xml配置<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ehcache> <ehcache name="shiro" updateCheck="false" monitoring="autodetect" dynamicConfig="true">
<diskStore path="java.io.tmpdir/ehcache" />
<!-- 默認緩存配置. 自動失效:最后一次訪問時間間隔300秒失效,若沒有訪問過自創建時間600秒失效。-> <defaultCache maxEntriesLocalHeap="1000" eternal="true" timeToIdleSeconds="0" timeToLiveSeconds="600" overflowToDisk="true" statistics="true" /> <!-- 會話緩存 --> <cache name="shiro-activeSessionCache" maxEntriesLocalHeap="10000" eternal="true" timeToIdleSeconds="0" timeToLiveSeconds="0" overflowToDisk="true" statistics="true" > <cacheEventListenerFactory class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"/> </cache> <!-- 監聽服務,用戶監聽其它應用通過過來的session操作 --> <cacheManagerPeerListenerFactory class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory" properties="hostName=localhost, port=40002, socketTimeoutMillis=2000"> </cacheManagerPeerListenerFactory>
<!-- 提供服務,當本應用對session操作時,會復制到其它應用(如果是多個應用則需要在rmiUrls屬性寫多個url,並用中豎線分割 --> <cacheManagerPeerProviderFactory class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory" properties="peerDiscovery=manual, rmiUrls=//localhost:40001/shiro-activeSessionCache"> </cacheManagerPeerProviderFactory> </ehcache>
2. 配置(ini或者config)
1)配置CacheManager
/** * 核心:SecurityManager,權限管理,這個類組合了登陸,登出,權限,session的處理,是個比較重要的類。 * 依賴項設置:Realm,SessionManager,CacheManager */ @Bean(name = "securityManager") public DefaultWebSecurityManager defaultWebSecurityManager(SystemAuthorizingRealm systemAuthorizingRealm, DefaultWebSessionManager sessionManager, EhCacheManager examCacheManager) { DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager(); defaultWebSecurityManager.setRealm(systemAuthorizingRealm); defaultWebSecurityManager.setSessionManager(sessionManager); EhCacheManager ehCacheManager = new EhCacheManager(); ehCacheManager.setCacheManagerConfigFile("classpath:ehcache.xml"); defaultWebSecurityManager.setCacheManager(examCacheManager); return defaultWebSecurityManager; }
2)配置SessionDAO
@Bean(name = "sessionDao") public EnterpriseCacheSessionDAO sessionDao(){ EnterpriseCacheSessionDAO sessionDao = new EnterpriseCacheSessionDAO(); sessionDao.setActiveSessionsCacheName("shiro-activeSessionCache"); return sessionDao; }
就這么簡單!
