對於分布式系統,一般都牽扯到Session共享問題,
而想實現Session共享,就要實現Session的持久化操作,即是將內存中的Session持久化至緩存數據庫。
SessionDAO是Shiro提供的一個數據交互層的interface接口,其作用是可以將Session寫入到數據庫
中,然后可以對Session進行增刪改查操作。
通過下面的UML圖來看一下,Shiro為我們操作Session提供了哪些API。
其中SessionDao是最頂級的接口,它有一個簡單的實現叫AbstractSessionDAO,而在AbstractSessionDAO下
又有兩個實現類,分別是CachingSessionDAO和MemorySessionDAO,CachingSessionDAO提供了緩存的操作,
而MemorySessionDAO可以讓我們在內存中操作Session。
而CachingSessionDAO是一個抽象類,它有一個簡單的實現EnterpriseCacheSessionDAO,一般在開發過程中推薦大家直接繼承EnterpriseCacheSessionDAO。
總結:
(1)AbstractSessionDAO
提供了SessionDAO的基礎實現,如生成會話ID等。
(2)CachingSessionDAO
提供了對開發者透明的會話緩存的功能,需要設置相應的CacheManager。
(3)EnterpriseCacheSessionDAO
提供了緩存功能的會話維護,默認情況下使用MapCache實現,內部使用
ConcurrentHashMap保存緩存的會話。
一下是結合項目:
xml
<bean id="cluterShiroSessionDao" class="com.platform.shiro.CluterShiroSessionDao"/>
<bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
<!-- 設置session過期時間為1小時(單位:毫秒),默認為30分鍾 -->
<property name="globalSessionTimeout" value="3600000"></property>
<property name="sessionValidationSchedulerEnabled" value="true"></property>
<property name="sessionIdUrlRewritingEnabled" value="false"></property>
<property name="sessionDAO" ref="cluterShiroSessionDao"/>
</bean>
CluterShiroSessionDao.java
public class CluterShiroSessionDao extends EnterpriseCacheSessionDAO {
//創建Session(它實現了CachingSessionDAO接口的方法)
@Override
protected Serializable doCreate(Session session) {
Serializable sessionId = super.doCreate(session);
final String key = Constant.SESSION_KEY + sessionId.toString();
setShiroSession(key, session);
return sessionId;
}
//根據sessionId讀取session信息(它實現了CachingSessionDAO接口的方法)
@Override
protected Session doReadSession(Serializable sessionId) {
Session session = super.doReadSession(sessionId);
if (null == session) {
final String key = Constant.SESSION_KEY + sessionId.toString();
session = getShiroSession(key);
}
return session;
}
//更新操作(它實現了CachingSessionDAO接口的方法)
@Override
protected void doUpdate(Session session) {
super.doUpdate(session);
final String key = Constant.SESSION_KEY + session.getId().toString();
setShiroSession(key, session);
}
//刪除操作(它實現了CachingSessionDAO接口的方法)
@Override
protected void doDelete(Session session) {
super.doDelete(session);
final String key = Constant.SESSION_KEY + session.getId().toString();
J2CacheUtils.remove(key);
}
private Session getShiroSession(String key) {
return (Session) J2CacheUtils.get(key);
}
private void setShiroSession(String key, Session session) {
J2CacheUtils.put(key, session);
}
}
