simple-spring-memcached统一缓存的使用实例
SpringBoot与Redis缓存集成实践

SpringBoot与Redis缓存集成实践一、引言随着现代应用程序的复杂性不断增加,缓存成为提高系统性能和响应速度的重要手段之一。
而SpringBoot与Redis的集成可以帮助我们更加高效地实现缓存功能。
本文将介绍SpringBoot与Redis缓存集成的实践,从配置Redis、使用RedisTemplate进行缓存操作以及解决缓存穿透与缓存雪崩等问题进行探讨。
二、配置Redis1. 引入依赖在pom.xml文件中添加SpringDataRedis的依赖:```xml<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency>```2. 配置Redis连接参数在application.properties或application.yml文件中配置Redis连接参数:```spring.redis.host=127.0.0.1spring.redis.port=6379spring.redis.database=0spring.redis.password=```其中,host为Redis服务器的IP地址,port为端口号,database为数据库索引,password为连接密码(如果有设置)。
3. 配置RedisTemplate在SpringBoot的配置类中,通过@Bean注解创建一个RedisTemplate的实例,并设置相关参数,例如连接工厂、序列化器等:```java@Configurationpublic class RedisConfig {@Beanpublic RedisTemplate<String, Object>redisTemplate(RedisConnectionFactory redisConnectionFactory) {RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();redisTemplate.setConnectionFactory(redisConnectionFactory);redisTemplate.setKeySerializer(new StringRedisSerializer());redisTemplate.setValueSerializer(newGenericJackson2JsonRedisSerializer());return redisTemplate;}}```在上述代码中,我们使用了StringRedisSerializer对key进行序列化,使用了GenericJackson2JsonRedisSerializer对value进行序列化。
使用spring自带的cache

结合测试类发现,显然第二次调用没有进service实现类5、下面补充几个概念@Cacheable、@CachePut、@CacheEvict 注释介绍通过上面的例子,我们可以看到 spring cache 主要使用两个注释标签,即 @Cacheable、@CachePut 和 @CacheEvict,我们总结一下其作用和配置方法。
表 1. @Cacheable 作用和配置方法@Cacheable 的作用主要针对方法配置,能够根据方法的请求参数对其结果进行缓存@Cacheable主要的参数value缓存的名称,在 spring 配置文件中定义,必须指定至少一个例如:@Cacheable(value=”mycache”) 或者@Cacheable(value={”cache1”,”cache2”}key缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合例如:@Cacheable(value=”testcache”,key=”#u serName”)condition缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存例如:@Cacheable(value=”testcache”,condition =”#userName.length()>2”)表 2. @CachePut 作用和配置方法@CachePut 的作用主要针对方法配置,能够根据方法的请求参数对其结果进行缓存,和 @Cacheable 不同的是,它每次都会触发真实方法的调用@CachePut主要的参数value缓存的名称,在 spring 配置文件中定义,必须指定至少一个例如:@Cacheable(value=”mycache”) 或者@Cacheable(value={”cache1”,”cache2”}key缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合例如:@Cacheable(value=”testcache”,key=”#us erName”)condition缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存例如:@Cacheable(value=”testcache”,condition =”#userName.length()>2”)表 3. @CacheEvict 作用和配置方法@CachEvict 的作用主要针对方法配置,能够根据一定的条件对缓存进行清空@CacheEvict 主要的参数value缓存的名称,在 spring 配置文件中定义,必须指定至少一个例如:@CachEvict(value=”mycach e”) 或者@CachEvict(value={”cache1”,”cache2”}key缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合例如:@CachEvict(value=”testcach e”,key=”#userName”)condition缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才清空缓存例如:@CachEvict(value=”testcach e”,condition=”#userName.lengt h()>2”)allEntries是否清空所有缓存内容,缺省为 false,如果指定为 true,则方法调用后将立即清空所有缓存例如:@CachEvict(value=”testcach e”,allEntries=true)beforeInvoca tion 是否在方法执行前就清空,缺省为 false ,如果指定为 true ,则在方法还没有执行的时候就清空缓存,缺省情况下,如果方法执行抛出异常,则不会清空缓存例如:@CachEvict(value=”testcach e”,beforeInvocation=true)。
spring+redis实现数据的缓存

314<property name="locations">5<list>67<value>classpath*:/META-INF/config/redis.properties</value>8</list>9</property>10</bean>1112<import resource="spring-redis.xml"/>4)、web.xml设置spring的总配置⽂件在项⽬启动时加载1<context-param>2<param-name>contextConfigLocation</param-name>3<param-value>classpath*:/META-INF/applicationContext.xml</param-value><!----> 4</context-param>5)、redis缓存⼯具类ValueOperations ——基本数据类型和实体类的缓存ListOperations ——list的缓存SetOperations ——set的缓存HashOperations Map的缓存1import java.io.Serializable;2import java.util.ArrayList;3import java.util.HashMap;4import java.util.HashSet;5import java.util.Iterator;6import java.util.List;7import java.util.Map;8import java.util.Set;910import org.springframework.beans.factory.annotation.Autowired;11import org.springframework.beans.factory.annotation.Qualifier;12import org.springframework.context.support.ClassPathXmlApplicationContext;13import org.springframework.data.redis.core.BoundSetOperations;14import org.springframework.data.redis.core.HashOperations;15import org.springframework.data.redis.core.ListOperations;16import org.springframework.data.redis.core.RedisTemplate;17import org.springframework.data.redis.core.SetOperations;18import org.springframework.data.redis.core.ValueOperations;19import org.springframework.stereotype.Service;2021@Service22public class RedisCacheUtil<T>23{2425 @Autowired @Qualifier("jedisTemplate")26public RedisTemplate redisTemplate;2728/**29 * 缓存基本的对象,Integer、String、实体类等30 * @param key 缓存的键值31 * @param value 缓存的值32 * @return缓存的对象33*/34public <T> ValueOperations<String,T> setCacheObject(String key,T value)35 {3637 ValueOperations<String,T> operation = redisTemplate.opsForValue();38 operation.set(key,value);39return operation;40 }4142/**43 * 获得缓存的基本对象。
Springboot使用cache缓存过程代码实例

Springboot使⽤cache缓存过程代码实例1.pom.xml<!-- Ehcache 坐标 --><dependency><groupId>net.sf.ehcache</groupId><artifactId>ehcache</artifactId></dependency>2.ehcache.xml<?xml version="1.0" encoding="UTF-8"?><ehcache><diskStore path="java.io.tmpdir"/><!--defaultCache:echcache的默认缓存策略 --><defaultCachemaxElementsInMemory="10000"eternal="false"timeToIdleSeconds="120"timeToLiveSeconds="120"maxElementsOnDisk="10000000"diskExpiryThreadIntervalSeconds="120"memoryStoreEvictionPolicy="LRU"><persistence strategy="localTempSwap"/></defaultCache><!--maxElementsInMemory设置成1,overflowToDisk设置成true,只要有⼀个缓存元素,就直接存到硬盘上去eternal设置成true,代表对象永久有效maxElementsOnDisk设置成0 表⽰硬盘中最⼤缓存对象数⽆限⼤diskPersistent设置成true表⽰缓存虚拟机重启期数据--><cache name="usercache"maxElementsInMemory="1"eternal="true"overflowToDisk="true"maxElementsOnDisk="0"diskPersistent="true"><!-- <persistence strategy="localTempSwap"/>--> <!--不能和diskPersistent 同时存在--></cache>diskStore是物理⽂件的存储路径,cache标签中的name是多cache时区分的唯⼀标识,和程序中初始化⽅法getCache("***")参数⼀致。
使用SpringCache设置缓存条件操作

使⽤SpringCache设置缓存条件操作⽬录Spring Cache设置缓存条件原理@Cacheable的常⽤属性及说明Root对象@CachePut的常⽤属性同@CacheableCache缓存配置1、pom.xml2、Ehcache配置⽂件3、配置类4、⽰例Spring Cache设置缓存条件原理从Spring3.1开始,Spring框架提供了对Cache的⽀持,提供了⼀个对缓存使⽤的抽象,通过在既有代码中添加少量它定义的各种 annotation,即能够达到缓存⽅法的返回对象的作⽤。
提供的主要注解有@Cacheable、@CachePut、@CacheEvict和@Caching,具体见下表:注解说明@Cacheable 可以标注在类或⽅法上:标注在⽅法上表⽰该⽅法⽀持数据缓存;标在类上表⽰该类的所有⽅法都⽀持数据缓存。
具体功能:在执⾏⽅法体之前,检查缓存中是否有相同key值的缓存存在,如果存在对应的缓存,直接返回缓存中的值;如果不存在对应的缓存,则执⾏相应的⽅法体获取数据,并将数据存储到缓存中。
@CachePut可以标注在类或⽅法上,表⽰⽀持数据缓存。
具体功能:在⽅法执⾏前不会检查缓存中是否存在相应的缓存,⽽是每次都会执⾏⽅法体,并将⽅法执⾏结果存储到缓存中,如果相应key值的缓存存在,则更新key对应的value值。
@CacheEvict可以标注在类或⽅法上,⽤于清除相应key值的缓存。
@Caching可以标注在类或⽅法上,它有三个属性cacheable、put、evict分别⽤于指定@Cacheable、@CachePut和@CacheEvict当需要在类上或⽅法上同时使⽤多个注解时,可以使⽤@Caching,如:@Caching(cacheable=@Cacheable("User"), evict = {@CacheEvict("Member"), @CacheEvict(value = "Customer", allEntries = true)})@Cacheable的常⽤属性及说明如下表所⽰:@Cacheable属性说明key表⽰缓存的名称,必须指定且⾄少要有⼀个值,⽐如:@Cacheable(value=“Dept”)或@Cacheable(value={“Dept”,“Depts”})condition表⽰是否需要缓存,默认为空,表⽰所有情况都会缓存。
SpringCache的简介和使用

SpringCache的简介和使⽤1、简介Spring 从 3.1 开始定义了 org.springframework.cache.Cache 和 org.springframework.cache.CacheManager 接⼝来统⼀不同的缓存技术;并⽀持使⽤ JCache(JSR-107)注解简化我们开发Cache 接⼝为缓存的组件规范定义,包含缓存的各种操作集合; Cache 接⼝下 Spring 提供了各种 xxxCache 的实现;如 RedisCache ,EhCacheCache , ConcurrentMapCache 等;每次调⽤需要缓存功能的⽅法时,Spring 会检查检查指定参数的指定的⽬标⽅法是否已经被调⽤过;如果有就直接从缓存中获取⽅法调⽤后的结果,如果没有就调⽤⽅法并缓存结果后返回给⽤户。
下次调⽤直接从缓存中获取2、整合SpringCache简化缓存开发1)引⼊依赖<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-cache</artifactId></dependency>2)添加配置spring.cache.type=redis3)测试使⽤缓存@Cacheable 触发将数据保存到缓存的操作@CacheEvict 将数据从缓存删除@CachePut 不影响⽅法执⾏更新缓存@Caching 组合以上多个操作@CacheConfig 在类级别,共享缓存的相同配置①、主启动类上添加 @EnableCache注解,开启缓存功能②、只需要使⽤注解就可以完成缓存操作当⽅法的结果需要缓存到数据库,在⽅法上加上 @CacheEnable注解/*1、每⼀个需要缓存的数据,我们都要来指定要放到哪个名字的缓存。
memcached集成spring配置及使用

xmlns:context="/schema/context"
xmlns:jaxws="/jaxws"
</property>
<propertyname="nagle">
<value>${memcache.nagle}</value>源自</property>
<propertyname="socketTO">
<value>${memcache.socketTO}</value>
</property>
</bean>
this.memCachedClient = memCachedClient;
}
public String getMemCachedTest(String str) {
//从缓存中取数据
String value = (String) memCachedClient.get(str);
// memCachedClient.flushAll();
return string;
}
}
<constructor-arg>
<value>memCachedPool</value>
</constructor-arg>
<propertyname="servers">
<list>
<value>${memcache.server}</value>
Spring缓存注解@Cacheable、@CacheEvict、@CachePut使用

Spring缓存注解@Cacheable、@CacheEvict、@CachePut使⽤从3.1开始,Spring引⼊了对Cache的⽀持。
其使⽤⽅法和原理都类似于Spring对事务管理的⽀持。
Spring Cache是作⽤在⽅法上的,其核⼼思想是这样的:当我们在调⽤⼀个缓存⽅法时会把该⽅法参数和返回结果作为⼀个键值对存放在缓存中,等到下次利⽤同样的参数来调⽤该⽅法时将不再执⾏该⽅法,⽽是直接从缓存中获取结果进⾏返回。
所以在使⽤Spring Cache的时候我们要保证我们缓存的⽅法对于相同的⽅法参数要有相同的返回结果。
使⽤Spring Cache需要我们做两⽅⾯的事:n 声明某些⽅法使⽤缓存n 配置Spring对Cache的⽀持和Spring对事务管理的⽀持⼀样,Spring对Cache的⽀持也有基于注解和基于XML配置两种⽅式。
下⾯我们先来看看基于注解的⽅式。
1 基于注解的⽀持Spring为我们提供了⼏个注解来⽀持Spring Cache。
其核⼼主要是@Cacheable和@CacheEvict。
使⽤@Cacheable标记的⽅法在执⾏后Spring Cache将缓存其返回结果,⽽使⽤@CacheEvict标记的⽅法会在⽅法执⾏前或者执⾏后移除Spring Cache中的某些元素。
下⾯我们将来详细介绍⼀下Spring基于注解对Cache的⽀持所提供的⼏个注解。
1.1 @Cacheable@Cacheable可以标记在⼀个⽅法上,也可以标记在⼀个类上。
当标记在⼀个⽅法上时表⽰该⽅法是⽀持缓存的,当标记在⼀个类上时则表⽰该类所有的⽅法都是⽀持缓存的。
对于⼀个⽀持缓存的⽅法,Spring会在其被调⽤后将其返回值缓存起来,以保证下次利⽤同样的参数来执⾏该⽅法时可以直接从缓存中获取结果,⽽不需要再次执⾏该⽅法。
Spring在缓存⽅法的返回值时是以键值对进⾏缓存的,值就是⽅法的返回结果,⾄于键的话,Spring⼜⽀持两种策略,默认策略和⾃定义策略,这个稍后会进⾏说明。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
simple-spring-memcached统一缓存的使用实例如何在一个中型的Java应用中使用Memcached缓存数据不是个简单的问题。
当某个缓存数据需要在多个系统间共享和失效时,必须要有统一的规划才能保证不出错。
经过各种实践,目前系统在使用Memcached缓存数据全部采用Simple-Spring-Memcached框架来完成,并统一规划各系统Spring和Cache key的配置。
下面对在使用过程中需要注意的点做一个详细说明:Cache整体规划目前我们系统中有两个不同的Memcached服务器:1session memcached服务器:主要存储用户的session2app memcached服务器: 主要用于缓存应用数据由于应用所有的缓存数据都放在app缓存上,为避免各应用的缓存数据出现冲突,必须规划好它们的命名空间。
所幸Simple-Spring-Memcached支持namespace的概念,因此对各应用的namespace前缀规定如下:应用namespace前缀goodscenter goodscentertrade tradeuic uic这个namespace在生成key时,将放在最前面,稍后会有例子详述。
同一个应用中存在许多需要缓存的对象,因此约定namespace前缀之后再加上缓存对象的类名。
例子如下:应用缓存对象完整的namespace 最终生成的keytrade TcRate (id为42) trade:TcRate trade:TcRate:12goodscenter GoodsDo(id为42) goodscenter:GoodsDo goodscenter:GoodsDo:12key的生成规则Simple-Spring-Memcached提供的针对单个对象的注解接口提供了两种key生成方式,详情见此文3AssignCache类注解通过assignKey指定cache的key4SingleCache类注解通过ParameterValueKeyProvider注解指定生成key的方法对于第一种只要求必须保证key不与其它的冲突,且namesapce符合规则。
第二种时,约定缓存的数据对象必须实现有带CacheKeyMethod的cacheKey方法,参考实现如下:@CacheKeyMethodpublic String cacheKey() {return this.getId();}目前@CacheKeyMethod只支持返回String的方法,需要改造成可接受Long,Integer 型的。
当前必须有单独的方法来作为缓存Key的生成器真实存放到Memcached的key的生成规则是:namespace:key。
如goodscenter的id为42的domain对象GoodsDo,按上述方式生成的key为:goodscenter:GoodsDo:42spring配置说明关于Simple-Spring-Memcached具体XML配置如下:<beans xmlns="/schema/beans"xmlns:xsi="/2001/XMLSchema-instance"xmlns:aop="/schema/aop"xmlns:context="/schema/context"xsi:schemaLocation="/schema/beans/schema/beans/spring-beans-3.0.xsd/schema/context/schema/context/spring-context.xsd/schema/aop/schema/aop/spring-aop-3.0.xsd"><import resource="classpath:simplesm-context.xml"/><aop:aspectj -autoproxy/><context:annotation -config/><bean name="appCache" class="com.google.code.ssm.CacheFactory"><property name="cacheClientFactory"><beanclass="com.google.code.ssm.providers.xmemcached.MemcacheClientFactoryImpl"/> </property><property name="addressProvider"><bean class="com.google.code.ssm.config.DefaultAddressProvider"><!--memcached服务器ip:port 可以是多个,格式为:127.0.0.1:11211,192.168.100.11:11211--><property name="address" value="{memcached.server}"/></bean></property><property name="configuration"><!-- memcached连接器的配置,具体的配置项参考这个类 --><beanclass="com.google.code.ssm.providers.XMemcachedConfiguration"><!--是否使用一致性哈希--><property name="consistentHashing" value="true"/><!--连接池--><property name="connectionPoolSize" value="10"/><property name="optimizeGet" value="true"/></bean></property><property name="cacheName"><!-- 该Memcached配置的Cache名称一个应用中存在多个Memcached时,各个配置的cacheName必须不同。
如果该值未设,系统默认为default --><value>appCache</value></property></bean></beans>Java代码中使用说明a. 注解方式使用直接使用注解来处理缓存及失效非常简单,下面是相应的例子:读取缓存:EventGoodsServiceClientImpl.java@Override@ReadThroughSingleCache(namespace = "goodscenter:EventGoodsDo", expiration = 60)@CacheName("appCache")public EventGoodsDo queryEventGoodsDo(@ParameterValueKeyProvider(order = 0) long goodsId, @ParameterValueKeyProvider(order = 1) long eventId) {return getRemoteServiceBean().queryEventGoodsDo(goodsId, eventId);更新缓存:EventGoodsDaoImpl.java@BridgeMethodMappings(value = {@BridgeMethodMapping(erasedParamTypes={Object.class},targetParamTypes ={com.hqb360.promotion.dao.entity.EventGoods.class},methodName = "update")})public class EventGoodsDaoImpl<EventGoods> extendsBaseDaoImpl<EventGoods> implements EventGoodsDao<EventGoods> {@Overridepublic DaoStatementName getDaoStatementName() {return new DefaultDaoStatementName() {public String getDomainName() {return "EventGoods";}};}@Override@InvalidateSingleCache(namespace = "goodscenter:EventGoodsDo")@CacheName("appCache")public void update(@ParameterValueKeyProvider EventGoods obj) throws DataAccessException {super.update(obj);}EventGoods.java@CacheKeyMethodpublic String getCacheKey() {return goodsId + CACHE_ID_SEPARATOR + eventId;}public static final String CACHE_ID_SEPARATOR = "/";上述代码需要注意的点5多个方法参数都作为cacheKey时,ParameterValueKeyProvider必须指明其order 值6多个方法参数作为cacheKey时,参数之间在/ 号分隔7EventGoodsDaoImpl类中的update方法参数接收的是一个泛型对象,因此必须在该类上配置BridgeMethodMappings。