Spring 是什么呢?首先它是一个开源的项目,而且目前非常活跃;它是一个基于 IOC 和 AOP 的构架多层 j2ee 系统的框架,但它不强迫你必须在每一层 中必须使用 Spring,因为它模块化的很好,允许你根据自己的需要选择使用它的某一个模块;它实现了很优雅的 MVC,对不同的数据访问技术提供了统一的接口,采用 IOC 使得可以很容易的实现 bean 的装配,提供了简洁的 AOP 并据此实现 Transcation Managment,等等
这篇文章主要为大家详细介绍了 Spring 搭配 Ehcache 实例, 具有一定的参考价值,感兴趣的小伙伴们可以参考一下
1 Ehcache 简介
EhCache 是一个纯 Java 的进程内缓存框架,具有快速、精干等特点,是 Hibernate 中默认的 CacheProvider。
Ehcache 是一种广泛使用的开源 Java 分布式缓存。主要面向通用缓存, Java EE 和轻量级容器。它具有内存和磁盘存储,缓存加载器, 缓存扩展, 缓存异常处理程序, 一个 gzip 缓存 servlet 过滤器, 支持 REST 和 SOAP api 等特点。
Ehcache 最初是由 Greg Luck 于 2003 年开始开发。2009 年, 该项目被 Terracotta 购买。软件仍然是开源, 但一些新的主要功能 (例如,快速可重启性之间的一致性的) 只能在商业产品中使用,例如 Enterprise EHCache and BigMemory。维基媒体 Foundationannounced 目前使用的就是 Ehcache 技术。
总之 Ehcache 还是一个不错的缓存技术,我们来看看 Spring 搭配 Ehcache 是如何实现的。
2 Spring 搭配 Ehcache
系统结果如下:
3 具体配置介绍
有这几部分的结合:
src:java 代码,包含拦截器,调用接口,测试类
src/cache-bean.xml:配置 Ehcache,拦截器,以及测试类等信息对应的 bean
src/ehcache.xml:Ehcache 缓存配置信息
webRoot/lib:库
4 详细内容介绍
4.1 src
4.1.1 拦截器
代码中首先配置了两个拦截器:
第一个拦截器为:
com.test.ehcache.CacheMethodInterceptor
内容如下:
- package com.test.ehcache;
- import java.io.Serializable;
- import net.sf.ehcache.Cache;
- import net.sf.ehcache.Element;
- import org.aopalliance.intercept.MethodInterceptor;
- import org.aopalliance.intercept.MethodInvocation;
- import org.springframework.beans.factory.InitializingBean;
- import org.springframework.util.Assert;
- public class CacheMethodInterceptor implements MethodInterceptor,
- InitializingBean {
- private Cache cache;
- public void setCache(Cache cache) {
- this.cache = cache;
- }
- public CacheMethodInterceptor() {
- super();
- }
- /**
- * 拦截ServiceManager的方法,并查找该结果是否存在,如果存在就返回cache中的值,
- * 否则,返回数据库查询结果,并将查询结果放入cache
- */
- public Object invoke(MethodInvocation invocation) throws Throwable {
- //获取要拦截的类
- String targetName = invocation.getThis().getClass().getName();
- //获取要拦截的类的方法
- String methodName = invocation.getMethod().getName();
- //获得要拦截的类的方法的参数
- Object[] arguments = invocation.getArguments();
- Object result;
- //创建一个字符串,用来做cache中的key
- String cacheKey = getCacheKey(targetName, methodName, arguments);
- //从cache中获取数据
- Element element = cache.get(cacheKey);
- if (element == null) {
- //如果cache中没有数据,则查找非缓存,例如数据库,并将查找到的放入cache
- result = invocation.proceed();
- //生成将存入cache的key和value
- element = new Element(cacheKey, (Serializable) result);
- System.out.println("-----进入非缓存中查找,例如直接查找数据库,查找后放入缓存");
- //将key和value存入cache
- cache.put(element);
- } else {
- //如果cache中有数据,则查找cache
- System.out.println("-----进入缓存中查找,不查找数据库,缓解了数据库的压力");
- }
- return element.getValue();
- }
- /**
- * 获得cache的key的方法,cache的key是Cache中一个Element的唯一标识,
- * 包括包名+类名+方法名,如:com.test.service.TestServiceImpl.getObject
- */
- private String getCacheKey(String targetName, String methodName, Object[] arguments) {
- StringBuffer sb = new StringBuffer();
- sb.append(targetName).append(".").append(methodName);
- if ((arguments != null) && (arguments.length != 0)) {
- for (int i = 0; i < arguments.length; i++) {
- sb.append(".").append(arguments[i]);
- }
- }
- return sb.toString();
- }
- /**
- * implement InitializingBean,检查cache是否为空 70
- */
- public void afterPropertiesSet() throws Exception {
- Assert.notNull(cache, "Need a cache. Please use setCache(Cache) create it.");
- }
- }
CacheMethodInterceptor 用来拦截以 "get" 开头的方法,注意这个拦截器是先拦截,后执行原调用接口。
还有一个拦截器:
com.test.ehcache.CacheAfterReturningAdvice
具体内容:
- package com.test.ehcache;
- import java.lang.reflect.Method;
- import java.util.List;
- import net.sf.ehcache.Cache;
- import org.springframework.aop.AfterReturningAdvice;
- import org.springframework.beans.factory.InitializingBean;
- import org.springframework.util.Assert;
- public class CacheAfterReturningAdvice implements AfterReturningAdvice,
- InitializingBean {
- private Cache cache;
- public void setCache(Cache cache) {
- this.cache = cache;
- }
- public CacheAfterReturningAdvice() {
- super();
- }
- public void afterReturning(Object arg0, Method arg1, Object[] arg2, Object arg3) throws Throwable {
- String className = arg3.getClass().getName();
- List list = cache.getKeys();
- for (int i = 0; i < list.size(); i++) {
- String cacheKey = String.valueOf(list.get(i));
- if (cacheKey.startsWith(className)) {
- cache.remove(cacheKey);
- System.out.println("-----清除缓存");
- }
- }
- }
- public void afterPropertiesSet() throws Exception {
- Assert.notNull(cache, "Need a cache. Please use setCache(Cache) create it.");
- }
- }
CacheAfterReturningAdvice 用来拦截以 "update" 开头的方法,注意这个拦截器是先执行原调用接口,后被拦截。
4.1.2 调用接口
接口名称为:
com.test.service.ServiceManager
来源: http://www.phperz.com/article/17/1201/359384.html