shiro安全框架扩展教程--如何扩展实现我们的缓存机制(第三方容器redis,memcached)

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介:             上一章我们讲解了如何扩展集中式的session管理方便我们集群的应用项目,无须再使用复制session的方式来完善用户体系;下面我主要分享如何扩展shiro里的缓存实...

            上一章我们讲解了如何扩展集中式的session管理方便我们集群的应用项目,无须再使用复制session的方式来完善用户体系;下面我主要分享如何扩展shiro里的缓存实现,

大家都知道有点规模的项目都必须会使用缓存这个好东西,所以一个好的框架基本都会包含一套多级缓存的机制,例如spring,hibernate等也会有自己一套,象第三方的oscache,ehcache等等;


不扯没营养的话了,还是说回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写的有哪些实现类

一个是org.apache.shiro.cache.ehcache.EhCache

一个是org.apache.shiro.cache.MapCache

然后看着名字我们就大概知道一个是基于encache框架来作为实现类基础,一个是以本地map来装载数据到内存达到缓存的效果,这里类的源码可以自己看看,比较简单,shiro入门后的都能看懂,但是这些实现类都不适合我用,我想要的是用memcached或是redis作为数据的缓存容器


下面我就来分享下自己的实现流程



上面我们已经看过shiro的cache接口,下面我们就实现一个序列化的cache实现类


/**
 * 
 * 缓存实现类,实现序列 接口方便对象存储于第三方容器(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实现我直接用mapcache实现类的源码然后增加实现序列化的接口,比较方便


然后我们把自己的资源搞到一个map里,然后new SimpleMapCache(Map)就生成一个缓存堆,最后添加到缓存管理器里面即可


下面我们看看如何实现缓存管理器


所以我们先实现一个自定义的缓存管理器接口方便我们操作每一个缓存堆


/**
 * 
 * 缓存管理器接口
 * 
 * @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;
}

接口已经定义好,我们就写一个实现类完成我们的逻辑,并且这个逻辑是把缓存堆对象放到memcached里面


/**
 * 
 * 缓存管理器实现类
 * 
 * @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的缓存管理器


/**
 * 
 * 安全框架缓存管理器实现类
 * 
 * @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的管理器实现类注入到需要的地方即可


<!-- 安全管理器 -->
	<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添加到我们的自己的管理器里面即可...


这个章节已经讲完了,谢谢大家的支持


欢迎拍砖...


相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
1月前
|
IDE 开发工具 Windows
鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之RowSplit容器组件
鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之RowSplit容器组件
51 0
|
2月前
|
IDE API 开发工具
鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之Counter容器组件
鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之Counter容器组件
42 1
|
2月前
|
IDE 开发工具 Windows
鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之ColumnSplit容器组件
鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之ColumnSplit容器组件
38 0
|
2月前
|
IDE API 开发工具
鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之Column容器组件
鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之Column容器组件
51 0
|
3月前
|
缓存 NoSQL 应用服务中间件
2.2.2 redis,memcached,nginx网络组件
2.2.2 redis,memcached,nginx网络组件
|
3月前
|
NoSQL Java 应用服务中间件
4.网络设计与redis、memcached、nginx组件(二)
4.网络设计与redis、memcached、nginx组件(二)
28 0
|
26天前
|
Kubernetes API 调度
总结归纳Kubernetes | 一站式速查知识,助您轻松驾驭容器编排技术(水平扩展控制)
总结归纳Kubernetes | 一站式速查知识,助您轻松驾驭容器编排技术(水平扩展控制)
49 0
|
1月前
|
IDE API 开发工具
鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之Scroll容器组件
鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之Scroll容器组件
75 0
|
2月前
|
IDE API 开发工具
鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之Row容器组件
鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之Row容器组件
32 1
|
2月前
|
IDE 开发工具 Windows
鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之FlowItem容器组件
鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之FlowItem容器组件
35 1