spring+ehcache 实现原理

简介: 引用:http://yaoweinan.iteye.com/blog/1199397 ehcache 大家都很熟悉,我这里主要通过总结记录下spring和ehcache结合的步骤,并对一些细节做详细的阐述。

引用:http://yaoweinan.iteye.com/blog/1199397

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>

 

 

相关文章
|
1月前
|
XML Java 开发者
Spring Boot中的bean注入方式和原理
Spring Boot中的bean注入方式和原理
50 0
|
1月前
|
传感器 Java API
Spring揭秘:Aware接口应用场景及实现原理!
Aware接口赋予了Bean更多自感知的能力,通过实现不同的Aware接口,Bean可以轻松地获取到Spring容器中的其他资源引用,像ApplicationContext、BeanFactory等。 这样不仅增强了Bean的功能,还提高了代码的可维护性和扩展性,从而让Spring的IoC容器变得更加强大和灵活。
124 0
Spring揭秘:Aware接口应用场景及实现原理!
|
1月前
|
缓存 Java API
【云原生】Spring Cloud Gateway的底层原理与实践方法探究
【云原生】Spring Cloud Gateway的底层原理与实践方法探究
|
1月前
|
前端开发 搜索推荐 Java
【Spring底层原理高级进阶】基于Spring Boot和Spring WebFlux的实时推荐系统的核心:响应式编程与 WebFlux 的颠覆性变革
【Spring底层原理高级进阶】基于Spring Boot和Spring WebFlux的实时推荐系统的核心:响应式编程与 WebFlux 的颠覆性变革
|
25天前
|
安全 Java 数据安全/隐私保护
【深入浅出Spring原理及实战】「EL表达式开发系列」深入解析SpringEL表达式理论详解与实际应用
【深入浅出Spring原理及实战】「EL表达式开发系列」深入解析SpringEL表达式理论详解与实际应用
54 1
|
25天前
|
存储 XML 缓存
【深入浅出Spring原理及实战】「缓存Cache开发系列」带你深入分析Spring所提供的缓存Cache功能的开发实战指南(一)
【深入浅出Spring原理及实战】「缓存Cache开发系列」带你深入分析Spring所提供的缓存Cache功能的开发实战指南
57 0
|
26天前
|
XML 缓存 Java
天天用 Spring,bean 实例化原理你懂吗
天天用 Spring,bean 实例化原理你懂吗
17 0
|
1月前
|
存储 Java 数据处理
Spring揭秘:ClassPathScanningProvider接口应用场景及实现原理!
ClassPathScanningCandidateComponentProvider是Spring框架中一个非常核心的类,它主要用于在类路径下扫描并发现带有特定注解的组件,支持诸如@ComponentScan、@Component、@Service、@Repository和@Controller等注解的自动扫描和注册。
Spring揭秘:ClassPathScanningProvider接口应用场景及实现原理!
|
1月前
|
前端开发 Java 数据管理
Spring MVC 工作原理解析
Spring MVC 工作原理解析
22 0
|
1月前
|
Java API 开发者
Spring揭秘:BeanDefinitionBuilder接口应用场景及实现原理!
BeanDefinitionBuilder类为Spring框架中的Bean定义提供了灵活且强大构建方式,通过API,开发者能够轻松创建和配置Bean,无需依赖繁琐的XML配置或注解。
Spring揭秘:BeanDefinitionBuilder接口应用场景及实现原理!