J2EE开发框架搭建(9) - memcached与spring提供的cache接口整合

spring 从3.x就提供了cache接口,spring默认实现的缓存是ehcache,spring的cache接口:

public interface Cache {
	String getName();
	Object getNativeCache();
	ValueWrapper get(Object key);
	<T> T get(Object key, Class<T> type);
	void put(Object key, Object value);
	void evict(Object key);
	void clear();
	interface ValueWrapper {
		Object get();
	}
}

从spring的cache接口,我们可以看出spring的cache模型就是在内存中画一片内存区域出来,为这盘内存指定名称,在这盘内存区域中以key-value的方式存放数据,画个图来说明cache的存取方式,用户和部门的缓存,名称分别为DepartCache和UserCache

1. 要使用spring的cache,首先要实现cacheManager, 可以参考spring对ehcache的实现,整合memcached的代码如下:

public class MemcachedCacheManager extends AbstractTransactionSupportingCacheManager {

	private ConcurrentMap<String, Cache> cacheMap = new ConcurrentHashMap<String, Cache>();
	private Map<String, Integer> expireMap = new HashMap<String, Integer>();   //缓存的时间
	private MemcachedClient memcachedClient;   //xmemcached的客户端

	public MemcachedCacheManager() {
	}

	@Override
	protected Collection<? extends Cache> loadCaches() {
		Collection<Cache> values = cacheMap.values();
		return values;
	}

	@Override
	public Cache getCache(String name) {
		Cache cache = cacheMap.get(name);
		if (cache == null) {
			Integer expire = expireMap.get(name);
			if (expire == null) {
				expire = 0;
				expireMap.put(name, expire);
			}
			cache = new MemcachedCache(name, expire.intValue(), memcachedClient);
			cacheMap.put(name, cache);
		}
		return cache;
	}

	public void setMemcachedClient(MemcachedClient memcachedClient) {
		this.memcachedClient = memcachedClient;
	}

	public void setConfigMap(Map<String, Integer> configMap) {
		this.expireMap = configMap;
	}

}

2. 接着看下MemcachedCache的实现,主要实现spring的cache接口

public class MemcachedCache implements Cache {

	private final String name;
	private final MemCache memCache;

	public MemcachedCache(String name, int expire, MemcachedClient memcachedClient) {
		this.name = name;
		this.memCache = new MemCache(name, expire, memcachedClient);
	}

	@Override
	public void clear() {
		memCache.clear();
	}

	@Override
	public void evict(Object key) {
		memCache.delete(key.toString());
	}

	@Override
	public ValueWrapper get(Object key) {
		ValueWrapper wrapper = null;
		Object value = memCache.get(key.toString());
		if (value != null) {
			wrapper = new SimpleValueWrapper(value);
		}
		return wrapper;
	}

	@Override
	public String getName() {
		return this.name;
	}

	@Override
	public MemCache getNativeCache() {
		return this.memCache;
	}

	@Override
	public void put(Object key, Object value) {
		memCache.put(key.toString(), value);
	}

	@Override
	@SuppressWarnings("unchecked")
	public <T> T get(Object key, Class<T> type) {
		Object cacheValue = this.memCache.get(key.toString());
		Object value = (cacheValue != null ? cacheValue : null);
		if (type != null && !type.isInstance(value)) {
			throw new IllegalStateException("Cached value is not of required type [" + type.getName() + "]: " + value);
		}
		return (T) value;
	}

}

3. spring提供的这套缓存api其实就是底层缓存框架与应用程序之间的中间层转换, 这里还有一个类就是MemCache,这个类主要是对应memcached缓存的模型,spring的缓存只是提供了一套api,具体的实现要根据底层使用的什么缓存框架:

MemCache.java

public class MemCache {
	private static Logger log = LoggerFactory.getLogger(MemCache.class);

	private Set<String> keySet = new HashSet<String>();
	private final String name;
	private final int expire;
	private final MemcachedClient memcachedClient;

	public MemCache(String name, int expire, MemcachedClient memcachedClient) {
		this.name = name;
		this.expire = expire;
		this.memcachedClient = memcachedClient;
	}

	public Object get(String key) {
		Object value = null;
		try {
			key = this.getKey(key);
			value = memcachedClient.get(key);
		} catch (TimeoutException e) {
			log.warn("获取 Memcached 缓存超时", e);
		} catch (InterruptedException e) {
			log.warn("获取 Memcached 缓存被中断", e);
		} catch (MemcachedException e) {
			log.warn("获取 Memcached 缓存错误", e);
		}
		return value;
	}

	public void put(String key, Object value) {
		if (value == null)
			return;

		try {
			key = this.getKey(key);
			memcachedClient.setWithNoReply(key, expire, value);
			keySet.add(key);
		} catch (InterruptedException e) {
			log.warn("更新 Memcached 缓存被中断", e);
		} catch (MemcachedException e) {
			log.warn("更新 Memcached 缓存错误", e);
		}
	}

	public void clear() {
		for (String key : keySet) {
			try {
				memcachedClient.deleteWithNoReply(this.getKey(key));
			} catch (InterruptedException e) {
				log.warn("删除 Memcached 缓存被中断", e);
			} catch (MemcachedException e) {
				log.warn("删除 Memcached 缓存错误", e);
			}
		}
	}

	public void delete(String key) {
		try {
			key = this.getKey(key);
			memcachedClient.deleteWithNoReply(key);
		} catch (InterruptedException e) {
			log.warn("删除 Memcached 缓存被中断", e);
		} catch (MemcachedException e) {
			log.warn("删除 Memcached 缓存错误", e);
		}
	}

	private String getKey(String key) {
		return name + "_" + key;
	}
}

4. 在spring的配置文件中使用MemcachedCacheManager

<cache:annotation-driven cache-manager="cacheManager" proxy-target-class="true" />    <!-- 开启缓存 -->
<bean id="memcachedClientBuilder" class="net.rubyeye.xmemcached.XMemcachedClientBuilder">   <!-- 配置memcached的缓存服务器 -->
	<constructor-arg>
		<list>
			<bean class="java.net.InetSocketAddress">
				<constructor-arg value="localhost" />
				<constructor-arg value="11211" />
			</bean>
		</list>
	</constructor-arg>
</bean>
<bean id="memcachedClient" factory-bean="memcachedClientBuilder" factory-method="build" destroy-method="shutdown" />
<bean id="cacheManager" class="com.hqhop.framework.common.cache.memcached.MemcachedCacheManager">
	<property name="memcachedClient" ref="memcachedClient" />
	<!-- 配置缓存时间 -->
	<property name="configMap">  
            <map>  
                <entry key="typeList" value="3600" />   <!-- key缓存对象名称   value缓存过期时间 -->
            </map>  
        </property>  
</bean>

5. 到此为止,spring和memcached整合就完成了,spring的缓存还提供了很多的注解@Cachable,@cachePut.....,这里不多说了。

参考地址 :

http://zj0121.iteye.com/blog/1852270

http://jinnianshilongnian.iteye.com/blog/2001040

时间: 2024-08-29 00:08:05

J2EE开发框架搭建(9) - memcached与spring提供的cache接口整合的相关文章

J2EE开发框架搭建目录

搭建的一个简单的J2EE开发框架 框架使用到的Java技术: 1. springmvc4   spring4 2. orm使用hibernate4 3. 安全框架使用shiro 4. 数据源使用druid 5. 整个框架使用maven管理 6. 缓存可以使用memcached,ehcached 7. 日志使用slf4j+log4j 项目下载地址:http://pan.baidu.com/s/1sjPSxtj J2EE开发框架搭建(1) - maven搭建多项目 J2EE开发框架搭建(2) - s

J2EE开发框架搭建(2) - springmvc4 + spring4 + hibernate4 整合

1. 打开hqhop-framework-parent项目下的pom.xml文件,添加springmvc4 , spring4 , hibernate4 ,以及数据源druid的依赖包,插件,依赖包版本号 <!-- data source 相关jar? --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version&g

J2EE开发框架搭建(5) - Java项目开发常用工具类

工具类下项目中的目录位置: 1. 中文转化成拼音.首字母  ,ChineseCharToPinYin,使用这个类的时候必须要加入pinyin.jar,pinyin.jar已经放到hqhop-framework-web项目的lib目录中: 使用方式: ChineseCharToPinYin只提供了两个方法: public static String getPinYin(String src) {.....}      将汉字转换为全拼 public static String getPinYinH

J2EE开发框架搭建(1) - maven搭建多项目

如何使用maven搭建多个项目 1. 创建一个maven project 2. 在frame-parent项目上面点击右键,新建Maven Module 3. 完成之后再建立一个web项目 4. 按照是以上的步骤建立,最后我建立的项目目录结构 框架使用到的Java技术: 1. springmvc4   spring4 2. orm使用hibernate4 3. 安全框架使用shiro 4. 数据源使用druid 5. 整个框架使用maven管理 6. 缓存可以使用memcached,ehcach

J2EE开发框架搭建(6) - 使用hibernate4完成基本Dao的封装

现在orm框架有很多,比如说guzz,hibernate,mybaits....,在封装一个框架的时候我们可以选择一种,也可以选择多种实现,供以后使用选择,这里我只实现了hibernate,目录结构图如下: 1. 首先查询BaseRepository这个接口,该接口泛型 :T 表示实体类型:ID表示主键类型:虽然在框架里面已经提供了查询的结构Searchable,但是Searchable也不能做到无限强大,比如一个多变关联查询,嵌套查询是没有办法完成的,所有只能自己编写sql语句,但是hiber

J2EE开发框架搭建(7) - 用hibernate实现类似mybaits把sql写在配置文字中

为了避免sql编写在Java代码里面,所以实现类型mybaits的功能,把sql语句编写在xml文件中,这样可以统一管理sql语句,维护更加容易. 1. 首先编写配置sql语句的xml的dtd文件,dtd文件主要是规范xml的,在编写sql语句的配置文件中主要有五个标签:select , update , insert , delete , import 其中select有两个属性id(保证所有的sql语句id唯一),resultClass(查询语句返回的对象,可以使具体的实体类,也可以是Map

J2EE开发框架搭建(3) - 查询条件封装

这一节主要想要说明一下框架中的查询条件接口 1. 条件查询的整个类结构图 2. 在hqhop-framework-common项目下面查询条件的的目录结构: 3. 打开SearchOperator.java , 该类包含了所有的查询操作符,是一个枚举类型: public enum SearchOperator { eq("等于", "="), ne("不等于", "!="), gt("大于", "

Spring4.X + spring MVC + Mybatis3 零配置应用开发框架搭建详解(1) - 基本介绍

Spring4.X + spring MVC + Mybatis3 零配置应用开发框架搭建详解(1) - 基本介绍 spring集成 mybatis Spring4.x零配置框架搭建 两年前一直在做后台的纯Java开发,很少涉及web开发这块,最近换了个纯的互联网公司,需要做Web后台管理系统,之前都是用xml配置的项目,接触了公司Spring4.x的零配置项目,觉得非常有感觉,不仅仅配置简单,而且条理清晰,所以,这里把学习的内容记录下来,一来加深对这块技术的印象,另外准备做个简单的教程,如果给

Sping Boot + Spring Security + Mybaits + Logback + JWT验证项目开发框架搭建

简介 本文介绍Sping Boot + Spring Security + Mybaits + Logback 项目开发框架搭建过程,并且实现JWT验证,代码已上传到github,地址在文章最后可以直接下载代码. 搭建过程 1 建立工程 工程目录如下: 2 上传至GitHub 使用Git shell 进入文件夹 添加远程仓库 上传到远程仓库 如果提示这个错误 Permission denied(publickey) 需要将本地ssh key添加到仓库 首先产生本地sshkey 将本地sshkey