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>

 

 

相关文章
|
9月前
|
缓存 Java 开发者
【Spring】原理:Bean的作用域与生命周期
本文将围绕 Spring Bean 的作用域与生命周期展开深度剖析,系统梳理作用域的类型与应用场景、生命周期的关键阶段与扩展点,并结合实际案例揭示其底层实现原理,为开发者提供从理论到实践的完整指导。
1059 22
|
9月前
|
人工智能 Java 开发者
【Spring】原理解析:Spring Boot 自动配置
Spring Boot通过“约定优于配置”的设计理念,自动检测项目依赖并根据这些依赖自动装配相应的Bean,从而解放开发者从繁琐的配置工作中解脱出来,专注于业务逻辑实现。
2946 0
|
监控 安全 Java
Spring AOP实现原理
本内容主要介绍了Spring AOP的核心概念、实现机制及代理生成流程。涵盖切面(Aspect)、连接点(Join Point)、通知(Advice)、切点(Pointcut)等关键概念,解析了JDK动态代理与CGLIB代理的原理及对比,并深入探讨了通知执行链路和责任链模式的应用。同时,详细分析了AspectJ注解驱动的AOP解析过程,包括切面识别、切点表达式匹配及通知适配为Advice的机制,帮助理解Spring AOP的工作原理与实现细节。
1632 13
|
8月前
|
XML Java 测试技术
《深入理解Spring》:IoC容器核心原理与实战
Spring IoC通过控制反转与依赖注入实现对象间的解耦,由容器统一管理Bean的生命周期与依赖关系。支持XML、注解和Java配置三种方式,结合作用域、条件化配置与循环依赖处理等机制,提升应用的可维护性与可测试性,是现代Java开发的核心基石。
|
8月前
|
XML Java 应用服务中间件
【SpringBoot(一)】Spring的认知、容器功能讲解与自动装配原理的入门,带你熟悉Springboot中基本的注解使用
SpringBoot专栏开篇第一章,讲述认识SpringBoot、Bean容器功能的讲解、自动装配原理的入门,还有其他常用的Springboot注解!如果想要了解SpringBoot,那么就进来看看吧!
753 2
|
存储 人工智能 自然语言处理
RAG 调优指南:Spring AI Alibaba 模块化 RAG 原理与使用
通过遵循以上最佳实践,可以构建一个高效、可靠的 RAG 系统,为用户提供准确和专业的回答。这些实践涵盖了从文档处理到系统配置的各个方面,能够帮助开发者构建更好的 RAG 应用。
6893 117
|
10月前
|
Java 关系型数据库 数据库
深度剖析【Spring】事务:万字详解,彻底掌握传播机制与事务原理
在Java开发中,Spring框架通过事务管理机制,帮我们轻松实现了这种“承诺”。它不仅封装了底层复杂的事务控制逻辑(比如手动开启、提交、回滚事务),还提供了灵活的配置方式,让开发者能专注于业务逻辑,而不用纠结于事务细节。
1203 1
|
11月前
|
缓存 安全 Java
Spring 框架核心原理与实践解析
本文详解 Spring 框架核心知识,包括 IOC(容器管理对象)与 DI(容器注入依赖),以及通过注解(如 @Service、@Autowired)声明 Bean 和注入依赖的方式。阐述了 Bean 的线程安全(默认单例可能有安全问题,需业务避免共享状态或设为 prototype)、作用域(@Scope 注解,常用 singleton、prototype 等)及完整生命周期(实例化、依赖注入、初始化、销毁等步骤)。 解析了循环依赖的解决机制(三级缓存)、AOP 的概念(公共逻辑抽为切面)、底层动态代理(JDK 与 Cglib 的区别)及项目应用(如日志记录)。介绍了事务的实现(基于 AOP
426 0
|
前端开发 Java 数据库连接
Spring核心原理剖析与解说
每个部分都是将一种巨大并且复杂的技术理念传达为更易于使用的接口,而这就是Spring的价值所在,它能让你专注于开发你的应用,而不必从头开始设计每一部分。
338 32
|
XML Java 开发者
Spring Boot开箱即用可插拔实现过程演练与原理剖析
【11月更文挑战第20天】Spring Boot是一个基于Spring框架的项目,其设计目的是简化Spring应用的初始搭建以及开发过程。Spring Boot通过提供约定优于配置的理念,减少了大量的XML配置和手动设置,使得开发者能够更专注于业务逻辑的实现。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,为开发者提供一个全面的理解。
382 0

热门文章

最新文章