`
yaoweinan
  • 浏览: 132743 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
社区版块
存档分类
最新评论

spring+ehcache 实现原理

 
阅读更多
 了解了一下spring +ehcache 这里对其实现做以简单介绍,仅仅个人理解,若有所误,请多指点。

ehcache 大家都很熟悉,我这里主要通过总结记录下spring和ehcache结合的步骤,并对一些细节做详细的阐述。

首先我们需要配置ehcache的配置文件包含了缓存路径,大小,过期时间等 注意里面的defaultcache不要删除否则会出错滴。然后我们在把ehcache的jar包导入。

其次 我们需要写了两个类 这两个类一个用来对查询的缓存和再查询的缓存调用(代码1),一个用来处理如果对某一资源做了改动或者新增,则清除这中资源的所有缓存(代码2)。 接下来我们在spring配置文件中配置ehcache(你也可以单独文件中写),包括ehcache的引用,工厂,再将自己写的两个拦截器配置好之后在配置两个符合代理使用的两个bean,分别将两个拦截器注入。

最后我们为自己写的service/dao 在spring配置,再为他们分别配置代理,代理所要拦截的东西就是前面的两个拦截器。

 

接下来我将配置的具体内容贴出来

 

 

 

代码1 写道
package com.my.cache.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.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Assert;

/**
* ehCache 查询缓存处理
* @author lyon.yao
*
*/
public class MethodCacheInterceptor implements MethodInterceptor,
InitializingBean {
private static final Log logger = LogFactory.getLog(MethodCacheInterceptor.class);
private Cache cache;
public void setCache(Cache cache) {
this.cache = cache;
}

public MethodCacheInterceptor() {
super();
}

/* (non-Javadoc)
* 检测cache对象是否为空
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
*/
@Override
public void afterPropertiesSet() throws Exception {
Assert.notNull(cache, "cache is null,please set a new cache");
}

/* (non-Javadoc)
* 过滤service/dao 方法如果缓存中存在直接返回 否则从数据库中查找结果返回并放入缓存
* @see org.aopalliance.intercept.MethodInterceptor#invoke(org.aopalliance.intercept.MethodInvocation)
*/
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
Object result=null;
String targetName = invocation.getThis().getClass().getName();
String methodName = invocation.getMethod().getName();
Object[] arguments = invocation.getArguments();
String cacheKey = getCacheKey(targetName, methodName, arguments);
Element element = cache.get(cacheKey);
if (element == null) {
logger.debug("Hold up method , Get method result and create cache........!");
result = invocation.proceed();
element = new Element(cacheKey, (Serializable) result);
cache.put(element);
}
return element.getValue();
}
/**
* 获得 cache key 的方法,cache key 是 Cache 中一个 Element 的唯一标识
* cache key 包括 包名+类名+方法名,如 com.co.cache.service.UserServiceImpl.getAllUser
* @param targetName
* @param methodName
* @param arguments
* @return
*/
private String getCacheKey(String targetName,String methodName,Object[] arguments) {
StringBuffer key = new StringBuffer();
key.append(targetName).append(".").append(methodName);
if ((arguments != null) && (arguments.length != 0)) {
for (int i = 0; i < arguments.length; i++) {
key.append(".").append(arguments[i]);
}
}
return key.toString();
}
}
代码2 写道
package com.my.cache.ehcache;

import java.lang.reflect.Method;
import java.util.List;

import net.sf.ehcache.Cache;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.aop.AfterReturningAdvice;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Assert;

/**
* 功能:进行插入、修改、删除对cache的清理
* @author lyon.yao
*
*/
public class MethodCacheAfterAdvice implements AfterReturningAdvice,
InitializingBean {
private static final Log logger = LogFactory.getLog(MethodCacheAfterAdvice.class);
private Cache cache;
public void setCache(Cache cache) {
this.cache = cache;
}
public MethodCacheAfterAdvice() {
super();
}
/* (non-Javadoc)
* 检测cache对象是否为空
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
*/
@Override
public void afterPropertiesSet() throws Exception {
Assert.notNull(cache, "cache is null,please set a new cache");
}

/* (non-Javadoc)
* 刷新cache
* @see org.springframework.aop.AfterReturningAdvice#afterReturning(java.lang.Object, java.lang.reflect.Method, java.lang.Object[], java.lang.Object)
*/
@Override
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);
}
logger.debug("remove cache " + cacheKey);
}
}

}
ehcache.xml 写道
<?xml version="1.0" encoding="UTF-8"?>
<ehcache>
<diskStore path="java.io.tmpdir"/>
<defaultCache
maxElementsInMemory="500"
eternal="false"
timeToIdleSeconds="300"
timeToLiveSeconds="1200"
overflowToDisk="true" />
<cache name="DEFAULT_CACHE"
maxElementsInMemory="5000"
eternal="false"
timeToIdleSeconds="500"
timeToLiveSeconds="500"
overflowToDisk="true"
/>
</ehcache>

 

 

 

 

写道
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<!-- 缓存管理 -->
<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" >
<property name="configLocation">
<value>classpath:ehcache.xml</value>
</property>
</bean>
<!-- 信息缓存 -->
<bean id="ehCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
<property name="cacheName">
<value>DEFAULT_CACHE</value>
</property>
<property name="cacheManager" ref="cacheManager" />
</bean>
<!-- find/create cache 拦截器 -->
<bean id="methodCacheInterceptor"
class="com.my.cache.ehcache.MethodCacheInterceptor">
<property name="cache">
<ref local="ehCache" />
</property>
</bean>
<!-- flush cache 拦截器 -->
<bean id="methodCacheAfterAdvice"
class="com.my.cache.ehcache.MethodCacheAfterAdvice">
<property name="cache">
<ref local="ehCache" />
</property>
</bean>
<bean id="methodCachePointCut"
class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="advice">
<ref local="methodCacheInterceptor"/>
</property>
<property name="patterns">
<list>
<value>.*find.*</value>
<value>.*get.*</value>
<value>.*list.*</value>
<value>.*query.*</value>
</list>
</property>
</bean>
<bean id="methodCachePointCutAdvice"
class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="advice">
<ref local="methodCacheAfterAdvice"/>
</property>
<property name="patterns">
<list>
<value>.*add.*</value>
<value>.*create.*</value>
<value>.*update.*</value>
<value>.*delete.*</value>
<value>.*remove.*</value>
</list>
</property>
</bean>
</beans>

 

applicationContext-sevice.xml 写道
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<import resource="cacheContext.xml"/>
<bean id="testServiceTarget" class="com.co.cache.test.TestServiceImpl"/>
<bean id="testService" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target">
<ref local="testServiceTarget"/>
</property>
<property name="interceptorNames">
<list>
<value>methodCachePointCut</value>
<value>methodCachePointCutAdvice</value>
</list>
</property>
</bean>
</beans>

 

 

分享到:
评论

相关推荐

    spring AOP实现查询缓存

    本代码通过使用spring aop+ehcache的技术,实现了方法级别的查询缓存,主要原理是 方法的完整路径+方法参数值,作为key,放入cache中,下次访问时先判断cache中是否有该key.

    Ehcache分布式缓存与其在spring中的使用

    主要讲解下encache的原理、分布式缓存集群环境配置、与在spring中的使用

    ehcache基本原理

    ehcache是一个用Java实现的使用简单,高速,实现线程安全的缓存管理类库,ehcache提供了用内存,磁盘文件存储,以及分布式存储方式等多种灵活的cache管理方案。同时ehcache作为开放源代码项目,采用限制比较宽松的...

    高效的缓存管理解决方案AutoLoadCache.zip

    设计思想及原理使用方法注解(Annotation)说明表达式的应用缓存删除注意事项缓存管理页面与Spring Cache的区别源码阅读已经实现基于aspectj,代码在com.jarvis.cache.aop.aspectj.AspectjAopInterceptor。...

    springall:spring技术选型与各类集成,含jvm原理、rpc服务、消息投递、应用缓存、限流、定时任务、流式计算、canal、爬虫等集成,可切到分支参考README

    使用Java语言实现一些算法,如果要查看C语言实现相关算法,请参照。 appcache 应用级缓存Guava、EhCache、MapDB使用示例。 canal 基于阿里开源DB日志订阅canal组件消费DB变更消息的客户端使用示例。 crawler java...

    SpringBoot新手学习手册

    7.1注解配置与EhCache使用 35 7.2使用Redis集成缓存 37 八、 热部署 37 8.1 什么是热部署 37 8.2 项目演示案例 37 8.3 热部署原理 37 8.4 Devtools依赖 38 8.5 Devtools原理 38 九、 监控管理 38 Actuator...

    单点登录源码

    Ehcache | 进程内缓存框架 | [http://www.ehcache.org/](http://www.ehcache.org/) ActiveMQ | 消息队列 | [http://activemq.apache.org/](http://activemq.apache.org/) JStorm | 实时流式计算框架 | ...

    mybatis学习笔记

    2.4.1 实现原理 20 2.4.2 Mapper.xml(映射文件) 20 2.4.3 Mapper.java(接口文件) 21 2.4.4 加载UserMapper.xml文件 22 2.4.5 测试 22 2.4.6 总结 23 3 SqlMapConfig.xml配置文件 24 3.1 配置内容 24 3.2 properties...

    JAVA上百实例源码以及开源项目

    百度云盘分享 ... Java实现的FTP连接与数据浏览程序,实现实例化可操作的窗口。  部分源代码摘录:  ftpClient = new FtpClient(); //实例化FtpClient对象  String serverAddr=jtfServer.getText();...

    JAVA上百实例源码以及开源项目源代码

    Java实现的FTP连接与数据浏览程序 1个目标文件 摘要:Java源码,网络相关,FTP Java实现的FTP连接与数据浏览程序,实现实例化可操作的窗口。 部分源代码摘录: ftpClient = new FtpClient(); //实例化FtpClient对象 ...

    网络架构师148讲视频课程

    │ 第10节:Spring+Mybatis实现DAO.avi │ 第11节:Mybatis的分页实现.avi │ 第12节:Service的实现以及模块化.avi │ 第13节:Spring MVC实现Web层开发.avi │ 第14节:新增和列表页面和分页tag.avi │ 第15节:带...

Global site tag (gtag.js) - Google Analytics