上一章我們講解了如何擴展集中式的session管理方便我們集群的應(yīng)用項目,無須再使用復(fù)制session的方式來完善用戶體系;下面我主要分享如何擴展shiro里的緩存實現(xiàn),
大家都知道有點規(guī)模的項目都必須會使用緩存這個好東西,所以一個好的框架基本都會包含一套多級緩存的機制,例如spring,hibernate等也會有自己一套,象第三方的oscache,ehcache等等;
不扯沒營養(yǎng)的話了,還是說回shiro的緩存,shiro的緩存比較簡單,我們可以看看shiro定義的cache接口源碼
- package org.apache.shiro.cache;
-
- import java.util.Collection;
- import java.util.Set;
-
- // Referenced classes of package org.apache.shiro.cache:
- // CacheException
-
- public interface Cache
- {
-
- public abstract Object get(Object obj)
- throws CacheException;
-
- public abstract Object put(Object obj, Object obj1)
- throws CacheException;
-
- public abstract Object remove(Object obj)
- throws CacheException;
-
- public abstract void clear()
- throws CacheException;
-
- public abstract int size();
-
- public abstract Set keys();
-
- public abstract Collection values();
- }
很明顯看到跟我們普通的cache差不多,也是CRUD等等方法,然后看看有shiro寫的有哪些實現(xiàn)類
一個是org.apache.shiro.cache.ehcache.EhCache
一個是org.apache.shiro.cache.MapCache
然后看著名字我們就大概知道一個是基于encache框架來作為實現(xiàn)類基礎(chǔ),一個是以本地map來裝載數(shù)據(jù)到內(nèi)存達(dá)到緩存的效果,這里類的源碼可以自己看看,比較簡單,shiro入門后的都能看懂,但是這些實現(xiàn)類都不適合我用,我想要的是用memcached或是redis作為數(shù)據(jù)的緩存容器
下面我就來分享下自己的實現(xiàn)流程
上面我們已經(jīng)看過shiro的cache接口,下面我們就實現(xiàn)一個序列化的cache實現(xiàn)類
- /**
- *
- * 緩存實現(xiàn)類,實現(xiàn)序列 接口方便對象存儲于第三方容器(Map存放鍵值對)
- *
- *
- */
- @SuppressWarnings("serial")
- public class SimpleMapCache implements Cache<Object, Object>, Serializable {
-
- private final Map<Object, Object> attributes;
- private final String name;
-
- public SimpleMapCache(String name, Map<Object, Object> backingMap) {
- if (name == null)
- throw new IllegalArgumentException("Cache name cannot be null.");
- if (backingMap == null) {
- throw new IllegalArgumentException("Backing map cannot be null.");
- } else {
- this.name = name;
- attributes = backingMap;
- }
- }
-
- public Object get(Object key) throws CacheException {
- return attributes.get(key);
- }
-
- public Object put(Object key, Object value) throws CacheException {
- return attributes.put(key, value);
- }
-
- public Object remove(Object key) throws CacheException {
- return attributes.remove(key);
- }
-
- public void clear() throws CacheException {
- attributes.clear();
- }
-
- public int size() {
- return attributes.size();
- }
-
- public Set<Object> keys() {
- Set<Object> keys = attributes.keySet();
- if (!keys.isEmpty())
- return Collections.unmodifiableSet(keys);
- else
- return Collections.emptySet();
- }
-
- public Collection<Object> values() {
- Collection<Object> values = attributes.values();
- if (!CollectionUtils.isEmpty(values))
- return Collections.unmodifiableCollection(values);
- else
- return Collections.emptySet();
- }
-
- public String toString() {
- return (new StringBuilder("SimpleMapCache '")).append(name).append("' (").append(attributes.size()).append(
- " entries)").toString();
- }
-
- }
其實上面的cache實現(xiàn)我直接用mapcache實現(xiàn)類的源碼然后增加實現(xiàn)序列化的接口,比較方便
然后我們把自己的資源搞到一個map里,然后new SimpleMapCache(Map)就生成一個緩存堆,最后添加到緩存管理器里面即可
下面我們看看如何實現(xiàn)緩存管理器
所以我們先實現(xiàn)一個自定義的緩存管理器接口方便我們操作每一個緩存堆
- /**
- *
- * 緩存管理器接口
- *
- * @author shadow
- *
- */
- public interface SimpleCacheManager {
-
- /**
- * 新增緩存堆到管理器
- *
- * @param name
- * @param cache
- */
- public abstract void createCache(String name, Cache<Object, Object> cache) throws CacheException;
-
- /**
- * 獲取緩存堆
- *
- * @param name
- * @return
- * @throws CacheException
- */
- public abstract Cache<Object, Object> getCache(String name) throws CacheException;
-
- /**
- * 移除緩存堆
- *
- * @param name
- * @throws CacheException
- */
- public abstract void removeCache(String name) throws CacheException;
-
- /**
- * 更新緩存堆
- *
- * @param name
- * @param cache
- */
- public abstract void updateCahce(String name, Cache<Object, Object> cache) throws CacheException;
-
- /**
- * 注銷管理器
- */
- public abstract void destroy() throws CacheException;
- }
接口已經(jīng)定義好,我們就寫一個實現(xiàn)類完成我們的邏輯,并且這個邏輯是把緩存堆對象放到memcached里面
- /**
- *
- * 緩存管理器實現(xiàn)類
- *
- * @author shadow
- *
- */
- public class SimpleCacheManagerImpl implements SimpleCacheManager {
-
- private MemcachedClient memcachedClient;
-
- public SimpleCacheManagerImpl(MemcachedClient memcachedClient) {
- if (memcachedClient == null) {
- throw new RuntimeException("必須存在memcached客戶端實例");
- }
- this.memcachedClient = memcachedClient;
- }
-
- @Override
- public void createCache(String name, Cache<Object, Object> cache) throws CacheException {
- try {
- memcachedClient.set(name, 0, cache);
- } catch (Exception e) {
- throw new CacheException(e);
- }
- }
-
- @Override
- public Cache<Object, Object> getCache(String name) throws CacheException {
- try {
- return memcachedClient.get(name);
- } catch (Exception e) {
- throw new CacheException(e);
- }
- }
-
- @Override
- public void removeCache(String name) throws CacheException {
- try {
- memcachedClient.delete(name);
- } catch (Exception e) {
- throw new CacheException(e);
- }
- }
-
- @Override
- public void updateCahce(String name, Cache<Object, Object> cache) throws CacheException {
- try {
- memcachedClient.replace(name, 0, cache);
- } catch (Exception e) {
- throw new CacheException(e);
- }
- }
-
- @Override
- public void destroy() throws CacheException {
- try {
- memcachedClient.shutdown();
- } catch (Exception e) {
- throw new CacheException(e);
- }
- }
-
- }
然后我們就開始把這自定義的管理器接入到shiro的緩存管理器
- /**
- *
- * 安全框架緩存管理器實現(xiàn)類
- *
- * @author shadow
- *
- */
- public class ShiroCacheManager implements CacheManager, Destroyable {
-
- private SimpleCacheManager simpleCacheManager;
-
- @Override
- public Cache<Object, Object> getCache(String name) throws CacheException {
- return simpleCacheManager.getCache(name);
- }
-
- @Override
- public void destroy() throws Exception {
- simpleCacheManager.destroy();
- }
-
- public SimpleCacheManager getSimpleCacheManager() {
- return simpleCacheManager;
- }
-
- public void setSimpleCacheManager(SimpleCacheManager simpleCacheManager) {
- this.simpleCacheManager = simpleCacheManager;
- }
-
- }
最后配置下這個shiro的管理器實現(xiàn)類注入到需要的地方即可
- <!-- 安全管理器 -->
- <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
- <property name="sessionManager" ref="sessionManager" />
- <property name="cacheManager" ref="shiroCacheManager" />
- <property name="realm" ref="simpleUserRealm" />
- </bean>
-
- <!-- 安全框架緩存管理器 -->
- <bean id="shiroCacheManager" class="com.silvery.security.shiro.cache.ShiroCacheManager">
- <property name="simpleCacheManager" ref="simpleCacheManager" />
- </bean>
-
- <!-- 擴展緩存管理器 -->
- <bean id="simpleCacheManager"
- class="com.silvery.security.shiro.cache.extend.impl.SimpleCacheManagerImpl">
- <constructor-arg ref="memcachedClient" />
- </bean>
配置好了之后,我們在需要地方把實例化的SimpeMapCache添加到我們的自己的管理器里面即可...
這個章節(jié)已經(jīng)講完了,謝謝大家的支持
歡迎拍磚...