博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
优雅的缓存开发,看这一篇文章就可以了「干货」
阅读量:4293 次
发布时间:2019-05-27

本文共 3033 字,大约阅读时间需要 10 分钟。

用Java打酱油 2017-10-01 00:08

优雅的缓存开发,看这一篇文章就可以了「干货」

缓存重要性及缓存开发的几个阶段,见,本文主要关注如何优雅的做缓存开发:

  • 基于注解的缓存开发,对应用代码无侵入性;

  • 可以方的切换第三方缓存框架,无需修改代码;

  • 服务调用方(缓存使用者)无需识别是缓存调用还是一般服务调用,举例说明:调用方在调用UserService.getUser(String userId)服务时,无需关心服务具体实现是基于缓存还是直接查询数据库,由服务提供者根据系统实现吞吐量来决定,系统初期压力不大,可以不使用缓存,待到有性能瓶颈了,修改服务实现支持缓存。

Spring cahe可以很好的满足以上需求,还能带来意外的小惊喜。

Spring cache简介

Spring cache基于注释(annotation)的缓存(cache)技术,它本质上不是一个具体的缓存实现方案(例如 EHCache 或者 Redis),而是一个对缓存使用的抽象,通过在既有代码中添加少量它定义的各种 annotation,即能够达到缓存方法的返回对象的效果。

Spring cache的缓存技术还具备相当的灵活性,不仅能够使用 SpEL(Spring Expression Language)来定义缓存的 key 和各种 condition,还提供开箱即用的缓存临时存储方案,也支持和主流的专业缓存例如 Redis集成。

其特点总结如下:

  • 通过少量的配置 annotation 注释即可使得既有代码支持缓存

  • 支持开箱即用 Out-Of-The-Box,即不用安装和部署额外第三方组件即可使用缓存

  • 支持 Spring Express Language,能使用对象的任何属性或者方法来定义缓存的 key 和 condition

  • 支持 AspectJ,并通过其实现任何方法的缓存支持

  • 支持自定义 key 和自定义缓存管理者,具有相当的灵活性和扩展性

干货就要先看示例

1.配置一个基于内存的缓存

优雅的缓存开发,看这一篇文章就可以了「干货」

配置缓存管理器

2.定义一个用户User实体类

优雅的缓存开发,看这一篇文章就可以了「干货」

pojo

3.定义UserService接口和UserServiceImpl,这个实现类是重点。在getUser方法上添加了@Cacheable注解,意思即是如果调用该方法,则先到名为userCache的缓存中根据id找User是否存在,如果不存在才会到数据库查询,并且将查询结果放到缓存中。

  • 名为userCache的缓存实现是org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean,在第1步中已经注册;

  • 在调用getUser方法时会先到缓存中查找;

  • getUser方法执行完成后会将结果缓存起来,以便下次从缓存中查询;

优雅的缓存开发,看这一篇文章就可以了「干货」

服务类

4.测试

当第一次执行时,因为缓存中没有数据,会查询数据库。第二次再次执行时,因为缓存中已经有数据了,则直接从缓存中获取结果。

优雅的缓存开发,看这一篇文章就可以了「干货」

运行结果

Spring cache开发

缓存实现

Spring cache是对缓存的抽象,并不负责具体缓存的实现。所以开发第一步即是配置缓存管理器和具体的缓存实现

  • 缓存管理器使用缺省的org.springframework.cache.support.SimpleCacheManager即可,无需改变;

  • 缓存实现,在实现的应用中可能会用到多种缓存实现,如基于内存(map)、Redis的,不同的项目使用的缓存实现也可能不同,如下配置了一种名为userCache的内存缓存实现。

优雅的缓存开发,看这一篇文章就可以了「干货」

缓存配置

@Cacheable

在方法调用之前执行,即先查询缓存,如果缓存中没有数据再执行方法并将结果缓存起来。常用于查询类服务

优雅的缓存开发,看这一篇文章就可以了「干货」

cacheable

属性 说明 示例
value 缓存的名称,在 spring 配置文件中定义,必须指定至少一个,如果是多个,则将结果写入多个缓存 @Cacheable(value={”cache1”,”cache2”}
key 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合 @CacheCacheable(value="userCache", key="#user.id" )
condition 满足缓存条件的数据才会放入缓存,condition在调用方法之前和之后都会判断 @CacheCacheable(value="userCache",condition="#user.id.length()>4" )
unless 满足条件不更新缓存,不像condition,该表达只在方法执行之后判断,此时可以拿到返回值result进行判断了 @CacheCacheable(value="userCache",condition="#user.id.length()>4" )//满足条件不更新缓存

@CachePut

在方法调用之后执行,即先执行方法,再缓存结果。常用于更新类服务。

优雅的缓存开发,看这一篇文章就可以了「干货」

cacheput

注:缓存key是user对象的id, 缓存结果是方法的返回值,无论是CachePut还是Cacheable缓存的结果都是方法的返回值

属性 说明 示例
value 缓存的名称,在 spring 配置文件中定义,必须指定至少一个,如果是多个,则将结果写入多个缓存 @Cacheable(value={”cache1”,”cache2”}
key 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合 @CacheCacheable(value="userCache", key="#user.id" )
condition 满足缓存条件的数据才会放入缓存,condition在调用方法之前和之后都会判断 @CacheCacheable(value="userCache",condition="#user.id.length()>4" )
unless 满足条件不更新缓存,不像condition,该表达只在方法执行之后判断,此时可以拿到返回值result进行判断了 @CacheCacheable(value="userCache",condition="#user.id.length()>4" )//满足条件不更新缓存

@CacheEvict

清理缓存。根据根据key清理缓存;清理所有缓存;根据条件清理缓存

优雅的缓存开发,看这一篇文章就可以了「干货」

cacheevict

属性 说明 示例
value 同CachePut  
key 同CachePut  
condition 同CachePut  
allEntries 是否清理所有缓存数据 @CacheEvict(value="userCache",allEntries=true)
beforeInvocation 是否在方法执行之前清理 @CacheEvict(value="userCache",beforeInvocation=false)

三种方式的对比

  • @Cacheable 根据请求参数缓存结果(方法返回值),在方法执行前调用;

  • @CachePut 根据请求参数缓存结果(方法返回值),在方法执行后调用;

  • @CachEvict 清理缓存,可以根据请求参数清理,也可以全部清理;可在方法执行前或后清理缓存;

注意

基于动态代理的实现,所以在对象内部调用时缓存不生效

优雅的缓存开发,看这一篇文章就可以了「干货」

内部调用不生效

转载地址:http://fyzws.baihongyu.com/

你可能感兴趣的文章
通向财务自由之路08_入市或市场时机选择
查看>>
通向财务自由之路09_知道何时收手:如何保护你的资本
查看>>
通向财务自由之路10_沉着应对
查看>>
走进我的交易室01_引子
查看>>
走进我的交易室02_交易什么市场
查看>>
走进我的交易室03_第一步成功的外部障碍
查看>>
走进我的交易室04_成功交易的 3 个 M
查看>>
走进我的交易室05_方法技术分析
查看>>
走进我的交易室06_交易
查看>>
走进我的交易室07_资金管理公式
查看>>
走进我的交易室08_有条理的交易者
查看>>
中低频量化交易策略研发01_引言
查看>>
中低频量化交易策略研发02_量化交易策略的研发流程
查看>>
中低频量化交易策略研发03_注意事项与应对
查看>>
中低频量化交易策略研发04_ 简单的择时策
查看>>
中低频量化交易策略研发05_推进分析
查看>>
中低频量化交易策略研发06_推进的择时策略
查看>>
史丹·温斯坦称傲牛熊市的秘密
查看>>
期货市场技术分析01_理论基础
查看>>
期货市场技术分析02_趋势的基本概念
查看>>