Spring Shiro基础组件 SessionDao

相关阅读

简介

数据访问对象设计模式规范,用于启用对企业信息系统的Session访问,提供CRUD方法;
提供getActiveSessions()方法,支持处理孤立Session,由ValidatingSessionManager调用;

核心方法

/**
 * 保存
 * 返回值和Session.getId()一致
 */
Serializable create(Session session);

/**
 * 获取
 */
Session readSession(Serializable sessionId) throws UnknownSessionException;

/**
 * 更新
 */
void update(Session session) throws UnknownSessionException;

/**
 * 删除
 */
void delete(Session session);

/**
 * 获取活跃的Session
 */
Collection<Session> getActiveSessions();

实现子类

public interface SessionDAO
    public abstract class AbstractSessionDAO implements SessionDAO
        public abstract class CachingSessionDAO extends AbstractSessionDAO implements CacheManagerAware
            public class EnterpriseCacheSessionDAO extends CachingSessionDAO
        public class MemorySessionDAO extends AbstractSessionDAO

AbstractSessionDAO

简介

SessionDao接口的抽象实现,支持对创建/获取Session的校验,支持可插拔的Session ID生成策略;

核心方法

// Session ID生成器
private SessionIdGenerator sessionIdGenerator;

/**
 * 构造方法
 */
public AbstractSessionDAO() {
    // 默认Session ID生成器为JavaUuidSessionIdGenerator
    this.sessionIdGenerator = new JavaUuidSessionIdGenerator();
}

/**
 * 生成Session ID
 * 由子类的doCreate()方法调用
 * 若子类实现基于EIS数据存储则不需要调用本方法
 */
protected Serializable generateSessionId(Session session) {
    if (this.sessionIdGenerator == null) {
        String msg = "sessionIdGenerator attribute has not been configured.";
        throw new IllegalStateException(msg);
    }
    return this.sessionIdGenerator.generateId(session);
}

/**
 * 保存
 * 算法模板
 */
public Serializable create(Session session) {
    Serializable sessionId = doCreate(session);
    // 校验Session ID
    verifySessionId(sessionId);
    return sessionId;
}

/**
 * 校验Session ID
 */
private void verifySessionId(Serializable sessionId) {
    if (sessionId == null) {
        String msg = "sessionId returned from doCreate implementation is null.  Please verify the implementation.";
        throw new IllegalStateException(msg);
    }
}

/**
 * 绑定Session ID到指定的Session
 * 由子类调用,若子类不关心Session的具体实现
 */
protected void assignSessionId(Session session, Serializable sessionId) {
    ((SimpleSession) session).setId(sessionId);
}

/**
 * 保存
 * 算法细节,由子类实现
 */
protected abstract Serializable doCreate(Session session);

/**
 * 获取
 * 算法模板
 */
public Session readSession(Serializable sessionId) throws UnknownSessionException {
    Session s = doReadSession(sessionId);
    if (s == null) {
        throw new UnknownSessionException("There is no session with id [" + sessionId + "]");
    }
    return s;
}

/**
 * 获取
 * 算法细节,由子类实现
 */
protected abstract Session doReadSession(Serializable sessionId);

CachingSessionDAO

简介

在组件和底层的EIS数据存储之间提供透明的缓存层;

核心方法

// 默认缓存名称
public static final String ACTIVE_SESSION_CACHE_NAME = "shiro-activeSessionCache";
// 缓存管理器
private CacheManager cacheManager;
// 缓存活跃Session
private Cache<Serializable, Session> activeSessions;
// 缓存名称
private String activeSessionsCacheName = ACTIVE_SESSION_CACHE_NAME;

/**
 * 获取活跃Session缓存
 */
private Cache<Serializable, Session> getActiveSessionsCacheLazy() {
    if (this.activeSessions == null) {
        this.activeSessions = createActiveSessionsCache();
    }
    return activeSessions;
}

/**
 * 创建活跃Session缓存
 */
protected Cache<Serializable, Session> createActiveSessionsCache() {
    Cache<Serializable, Session> cache = null;
    CacheManager mgr = getCacheManager();
    if (mgr != null) {
        String name = getActiveSessionsCacheName();
        cache = mgr.getCache(name);
    }
    return cache;
}

/**
 * 保存
 */
public Serializable create(Session session) {
    Serializable sessionId = super.create(session);
    // 缓存Session
    cache(session, sessionId);
    return sessionId;
}

/**
 * 获取缓存的Session
 */
protected Session getCachedSession(Serializable sessionId) {
    Session cached = null;
    if (sessionId != null) {
        Cache<Serializable, Session> cache = getActiveSessionsCacheLazy();
        if (cache != null) {
            cached = getCachedSession(sessionId, cache);
        }
    }
    return cached;
}

/**
 * 从指定缓存中获取Session
 */
protected Session getCachedSession(Serializable sessionId, Cache<Serializable, Session> cache) {
    return cache.get(sessionId);
}

/**
 * 缓存Session
 */
protected void cache(Session session, Serializable sessionId) {
    if (session == null || sessionId == null) {
        return;
    }
    Cache<Serializable, Session> cache = getActiveSessionsCacheLazy();
    if (cache == null) {
        return;
    }
    cache(session, sessionId, cache);
}

/**
 * 向指定缓存中放入Session
 */
protected void cache(Session session, Serializable sessionId, Cache<Serializable, Session> cache) {
    cache.put(sessionId, session);
}

/**
 * 获取
 */
public Session readSession(Serializable sessionId) throws UnknownSessionException {
    // 先从缓存中获取
    Session s = getCachedSession(sessionId);
    if (s == null) {
        // 缓存中不存在则从底层数据存储中获取
        s = super.readSession(sessionId);
    }
    return s;
}

/**
 * 更新
 * 算法模板
 */
public void update(Session session) throws UnknownSessionException {
    doUpdate(session);
    if (session instanceof ValidatingSession) {
        // 校验Session有效性
        if (((ValidatingSession) session).isValid()) {
            // 更新缓存
            cache(session, session.getId());
        } else {
            // Session失效,清除缓存
            uncache(session);
        }
    } else {
        // 更新缓存
        cache(session, session.getId());
    }
}

/**
 * 更新
 * 算法细节,由子类实现
 */
protected abstract void doUpdate(Session session);

/**
 * 删除
 * 算法模板
 */
public void delete(Session session) {
    // 清除缓存
    uncache(session);
    // 删除
    doDelete(session);
}

/**
 * 删除
 * 算法细节,由子类实现
 */
protected abstract void doDelete(Session session);

/**
 * 清除缓存
 */
protected void uncache(Session session) {
    if (session == null) {
        return;
    }
    Serializable id = session.getId();
    if (id == null) {
        return;
    }
    Cache<Serializable, Session> cache = getActiveSessionsCacheLazy();
    if (cache != null) {
        cache.remove(id);
    }
}

/**
 * 获取活跃的Session
 */
public Collection<Session> getActiveSessions() {
    Cache<Serializable, Session> cache = getActiveSessionsCacheLazy();
    if (cache != null) {
        return cache.values();
    } else {
        return Collections.emptySet();
    }
}

EnterpriseCacheSessionDAO

简介

基于内存映射的CacheManager,本质上无逻辑处理,依赖父类缓存实现;

核心方法

/**
 * 构造方法
 */
public EnterpriseCacheSessionDAO() {
    // 设置基于内存映射的CacheManager
    setCacheManager(new AbstractCacheManager() {
        @Override
        protected Cache<Serializable, Session> createCache(String name) throws CacheException {
            return new MapCache<Serializable, Session>(name, new ConcurrentHashMap<Serializable, Session>());
        }
    });
}

/**
 * 保存
 */
protected Serializable doCreate(Session session) {
    Serializable sessionId = generateSessionId(session);
    assignSessionId(session, sessionId);
    return sessionId;
}

/**
 * 获取
 * 不做处理,依赖父类缓存实现
 */
protected Session doReadSession(Serializable sessionId) {
    return null; //should never execute because this implementation relies on parent class to access cache, which
    //is where all sessions reside - it is the cache implementation that determines if the
    //cache is memory only or disk-persistent, etc.
}

/**
 * 更新
 * 不做处理,依赖父类缓存实现
 */
protected void doUpdate(Session session) {
    //does nothing - parent class persists to cache.
}

/**
 * 删除
 * 不做处理,依赖父类缓存实现
 */
protected void doDelete(Session session) {
    //does nothing - parent class removes from cache.
}

MemorySessionDAO

简介

基于内存的SessionDao接口的简单实现,Session存储在内存的ConcurrentMap中;

核心方法

// Session集合
private ConcurrentMap<Serializable, Session> sessions;

/**
 * 保存
 * 算法细节
 */
protected Serializable doCreate(Session session) {
    // 生成Session ID
    Serializable sessionId = generateSessionId(session);
    // 绑定Session ID
    assignSessionId(session, sessionId);
    // 存储Session
    storeSession(sessionId, session);
    return sessionId;
}

/**
 * 存储
 */
protected Session storeSession(Serializable id, Session session) {
    if (id == null) {
        throw new NullPointerException("id argument cannot be null.");
    }
    return sessions.putIfAbsent(id, session);
}

/**
 * 获取
 * 算法细节
 */
protected Session doReadSession(Serializable sessionId) {
    return sessions.get(sessionId);
}

/**
 * 更新
 */
public void update(Session session) throws UnknownSessionException {
    storeSession(session.getId(), session);
}

/**
 * 删除
 */
public void delete(Session session) {
    if (session == null) {
        throw new NullPointerException("session argument cannot be null.");
    }
    Serializable id = session.getId();
    if (id != null) {
        sessions.remove(id);
    }
}

/**
 * 获取活跃的Session
 */
public Collection<Session> getActiveSessions() {
    Collection<Session> values = sessions.values();
    if (CollectionUtils.isEmpty(values)) {
        return Collections.emptySet();
    } else {
        return Collections.unmodifiableCollection(values);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值