基于spring 方法级缓存的多种实现
作者:刘竹青 发布时间:2022-12-14 18:31:38
方案实施
1、 spring和ehcache集成
主要获取ehcache作为操作ehcache的对象。
spring.xml中注入ehcacheManager和ehCache对象,ehcacheManager是需要加载ehcache.xml配置信息,创建ehcache.xml中配置不同策略的cache。
<!-- ehCache 配置管理器 -->
<bean id="ehcacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
<property name="configLocation" value="classpath:ehcache.xml" />
<!--true:单例,一个cacheManager对象共享;false:多个对象独立 -->
<property name="shared" value="true" />
<property name="cacheManagerName" value="ehcacheManager" />
</bean> <!-- ehCache 操作对象 -->
<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">
<property name="cacheManager" ref="ehcacheManager"/>
</bean>
<!-- 启用缓存注解功能(请将其配置在Spring主配置文件中) -->
<cache:annotation-driven cache-manager="cacheManager"/>
2、 spring和自带的缓存支持
<!-- Spring自己的基于java.util.concurrent.ConcurrentHashMap实现的缓存管理器(该功能是从Spring3.1开始提供的) -->
<bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">
<property name="caches">
<set>
<bean name="SimplePageCachingFilter" class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" />
</set>
</property>
</bean>
3.spring和redis集成
主要获取redisTemplate作为操作redis的对象。
redis.properties配置信息
#host 写入redis服务器地址
redis.ip=127.0.0.1
#Port
redis.port=6379
#Passord
#redis.password=123456
#连接超时30000
redis.timeout=30
#最大分配的对象数
redis.pool.maxActive=100
#最大能够保持idel状态的对象数
redis.pool.maxIdle=30
#当池内没有返回对象时,最大等待时间
redis.pool.maxWait=1000
#当调用borrow Object方法时,是否进行有效性检查
redis.pool.testOnBorrow=true
#当调用return Object方法时,是否进行有效性检查
redis.pool.testOnReturn=true
spring注入jedisPool、redisConnFactory、redisTemplate对象
<!-- 加载redis.propertis -->
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations" value="classpath:redis.properties"/>
</bean>
<!-- Redis 连接池 -->
<bean id="jedisPool" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxTotal" value="${redis.pool.maxActive}" />
<property name="maxIdle" value="${redis.pool.maxIdle}" />
<property name="testOnBorrow" value="${redis.pool.testOnBorrow}" />
<property name="testOnReturn" value="${redis.pool.testOnReturn}" />
<property name="maxWaitMillis" value="${redis.pool.maxWait}" />
</bean>
<!-- Redis 连接工厂 -->
<bean id="redisConnFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<property name="hostName" value="${redis.ip}" />
<property name="port" value="${redis.port}" />
<!-- property name="password" value="${redis.password}" -->
<property name="timeout" value="${redis.timeout}" />
<property name="poolConfig" ref="jedisPool" />
</bean>
<!-- redis 操作对象 -->
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="redisConnFactory" />
</bean>
<!-- 自定义缓存 -->
<bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">
<property name="caches">
<set>
<bean class="org.cpframework.cache.redis.RedisCache">
<property name="redisTemplate" ref="redisTemplate" />
<property name="name" value="default"/>
</bean>
</set>
</property>
</bean>
<!-- 启用缓存注解功能(请将其配置在Spring主配置文件中) -->
<cache:annotation-driven cache-manager="cacheManager"/>
4.spring 缓存注解解释
缓存注解有以下三个:
@Cacheable @CacheEvict @CachePut
1.
@Cacheable(value=”accountCache”),这个注释的意思是,当调用这个方法的时候,会从一个名叫 accountCache 的缓存中查询,如果没有,则执行实际的方法,并将执行的结果存入缓存中,否则返回缓存中的对象。这里的缓存中的 key 就是参数 userName,value 就是 Account 对象。“accountCache”缓存是在 spring*.xml 中定义的名称。
例子:
@Cacheable(value="accountCache")// 使用了一个缓存名叫 accountCache
public Account getAccountByName(String userName) {
// 方法内部实现不考虑缓存逻辑,直接实现业务
System.out.println("real query account."+userName);
return getFromDB(userName);
}
condition:用来条件判断,满足条件的则进行缓存
例子2:
@Cacheable(value="accountCache",condition="#userName.length() <=4")// 缓存名叫 accountCache
public Account getAccountByName(String userName) {
// 方法内部实现不考虑缓存逻辑,直接实现业务
return getFromDB(userName);
}
2.
@CacheEvict 注释来标记要清空缓存的方法,当这个方法被调用后,即会清空缓存。注意其中一个 @CacheEvict(value=”accountCache”,key=”#account.getName()”),其中的 Key 是用来指定缓存的 key 的,这里因为我们保存的时候用的是 account 对象的 name 字段,所以这里还需要从参数 account 对象中获取 name 的值来作为 key,前面的 # 号代表这是一个 SpEL 表达式,此表达式可以遍历方法的参数对象
例子3:
@CacheEvict(value="accountCache",key="#account.getName()")// 清空accountCache 缓存
public void updateAccount(Account account) {
updateDB(account);
}
@CacheEvict(value="accountCache",allEntries=true)// 清空accountCache 缓存
public void reload() {
reloadAll()
}
@Cacheable(value="accountCache",condition="#userName.length() <=4")// 缓存名叫 accountCache
public Account getAccountByName(String userName) {
// 方法内部实现不考虑缓存逻辑,直接实现业务
return getFromDB(userName);
}
3.
@CachePut 注释,这个注释可以确保方法被执行,同时方法的返回值也被记录到缓存中,实现缓存与数据库的同步更新。
@CachePut(value="accountCache",key="#account.getName()")// 更新accountCache 缓存
public Account updateAccount(Account account) {
return updateDB(account);
}
附录:
@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=”#userName”) |
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=”#userName”) |
condition | 缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存 | 例如: @Cacheable(value=”testcache”,condition=”#userName.length()>2”) |
表 3. @CacheEvict 作用和配置方法
@CachEvict 的作用 主要针对方法配置,能够根据一定的条件对缓存进行清空
@CacheEvict 主要的参数 | ||
value | 缓存的名称,在 spring 配置文件中定义,必须指定至少一个 | 例如: @CachEvict(value=”mycache”) 或者 @CachEvict(value={”cache1”,”cache2”} |
key | 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合 | 例如: @CachEvict(value=”testcache”,key=”#userName”) |
condition | 缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才清空缓存 | 例如: @CachEvict(value=”testcache”, condition=”#userName.length()>2”) |
allEntries | 是否清空所有缓存内容,缺省为 false,如果指定为 true,则方法调用后将立即清空所有缓存 | 例如: @CachEvict(value=”testcache”,allEntries=true) |
beforeInvocation | 是否在方法执行前就清空,缺省为 false,如果指定为 true,则在方法还没有执行的时候就清空缓存,缺省情况下,如果方法执行抛出异常,则不会清空缓存 | 例如: @CachEvict(value=”testcache”,beforeInvocation=true) |
来源:http://www.cnblogs.com/liuzhuqing/p/7552747.html


猜你喜欢
- 概述在使用maven进行Java项目的开发过程中,难免会有些公共的私有库,这些库是不太方便放到中央仓库的,可以通过Nexus搭建一个私有仓库
- 概览阿里巴巴在2018年7月份发布Nacos, Nacos是一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。并表示在6-8个
- Java原生SPI面向接口编程+策略模式实现建立接口Robotpublic interface Robot { /
- 本文实例讲述了Android编程实现启动界面的方法。分享给大家供大家参考,具体如下:最近在弄一个程序启动界面程序,在这里贴下代码。解释一下:
- 上一篇JavaMail入门第三篇 发送邮件中,我们学会了如何用JavaMail API提供的Transport类发送邮件,同样,JavaMa
- 关于页面渲染其实在工作中,一直都是前后端分离,也就是说,我的工作从来都是提供接口,而不写 html css js 之类的,所以在这方面也没有
- 找了半天没有找到postgresql中关于array数组类型的字段如何对应到java中的数据类型,后来找到了mybatis的TypeHand
- 本文实例为大家分享了java实现猜数游戏的具体代码,供大家参考,具体内容如下有开始界面,可以设置范围,设置猜的次数代码如下:public s
- CamShift算法全称是“Continuously Adaptive Mean-Shift”(连续的自适应MeanShift算法),是对M
- 一、查看线程的运行状态题目线程有以下6种状态:新建、运行、阻塞、等待、计时等待和终止。new新线程时,线程处于新建 状态。调用start()
- 由于 Spring 拥有对象的管理权,所以我们也需要拥有较为高效的对象存储和取出的手段,下面我们来分别总结一下:存对象配置文件在存储对象之前
- 电话号码输入框需求:三位,七位后有空格删除倒数第四,第八位会将空格也删除使用TextWatcherWhen an object of a t
- springmvc的图片上传1.导入相应的pom依赖 <dependency> <groupId>co
- 下拉刷新对于一个app来说是必不可少的一个功能,在早期大多数使用的是chrisbanes的PullToRefresh,或是修改自该框架的其他
- 本文实例为大家分享了抢红包源码,供大家参考,具体内容如下1. 正确获取红包流程2. 软件介绍2.1 效果图:2.2 功能介绍2.2.1 账号
- 这阵子在做Lephone的适配,测试组提交一个bug:标题栏的文字较长时没有显示完全,其实这并不能算个bug,并且这个问题在以前其他机器也没
- 编程是一门艺术,大批量的改动显然是非常丑陋的做法,用心的琢磨写的代码让它变的更美观。在有些情况下,一个客户不能或者不想直接访问另一个对象,这
- 一、问题描述LBS位置服务是android应用中重要的功能,应用越来越广泛,下面我们逐步学习和实现lbs相关的应用如定位、地图、导航等,首先
- jdk中自带了很多工具可以用于性能分析,位于jdk的bin目录下,jvisualvm工具可以以图形化的方式更加直观的监控本地以及远程的jav
- 说实话,对于xUtils,是我最近才用到的开发框架(也是刚接触),对于其功能不得不说,简化了很多的开发步骤,可以说是非常好的开发