摘要
日常开发中, 需要用到各种各样的框架来实现 API, 系统的构建. 作为程序员, 除了会使用框架还必须要了解框架工作的原理. 这样可以便于我们排查问题, 和自定义的扩展. 那么如何去学习框架呢. 通常我们通过阅读文档, 查看源码, 然后又很快忘记. 始终不能融汇贯通. 本文主要基于 Spring Cache 扩展为例, 介绍如何进行高效的源码阅读.
SpringCache 的介绍
为什么以 Spring Cache 为例呢, 原因有两个
Spring 框架是 web 开发最常用的框架, 值得开发者去阅读代码, 吸收思想
缓存是企业级应用开发必不可少的, 而随着系统的迭代, 我们可能会需要用到内存缓存, 分布式缓存. 那么 Spring Cache 作为胶水层, 能够屏蔽掉我们底层的缓存实现.
一句话解释 Spring Cache: 通过注解的方式, 利用 AOP 的思想来解放缓存的管理.
step1 查看文档
首先通过查看官方文档, 概括了解 Spring Cache https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-caching.html
重点两点
两个接口抽象 Cache , CacheManager , 具体的实现都是基于这两个抽象实现. 典型的 SPI 机制, 和 eat your dog food. 当需要提供接口给外部调用, 首先自己内部的实现也必须基于同样一套抽象机制
The cache abstraction does not provide an actual store and relies on abstraction materialized by the org.springframework.cache.Cache and org.springframework.cache.CacheManager interfaces.
Spring Cache 提供了这些缓存的实现, 如果没有一种 CacheManage , 或者 CacheResolver , 会按照指定的顺序去实现
- If you have not defined a bean of type CacheManager or a CacheResolver named cacheResolver (see CachingConfigurer), Spring Boot tries to detect the following providers (in the indicated order): 1.Generic 2.JCache (JSR-107) (EhCache 3, Hazelcast, Infinispan, and others) 3.EhCache 2.x 4.Hazelcast 5.Infinispan 6.Couchbase 7.Redis 8.Caffeine 9.Simple
- step2 run demo
对 Spring Cache 有了一个大概的了解后, 我们首先使用起来, 跑个 demo.
定义一个用户查询方法
配置一个 CacheManager
API 调用
step3 debug 查看实现
demo 跑起来后, 就是 debug 看看代码如何实现的了. 因为直接看源代码的, 没有调用关系, 看起来会一头雾水. 通过 debug 能够使你更快了解一个实现.
通过 debug 我们会发现主要控制逻辑是在切面 CacheAspectSupport 会先根据 cache key 找缓存数据, 没有的话 put 进去.
step4 实现扩展
知道如何使用 Spring Cache 后, 我们需要进一步思考, 就是如何扩展. 那么带着问题出发. 比如 Spring Cache 不支持批量 key 的缓存, 像上文我们举的例子, 我们希望缓存的 key 是 userId, 而不是 Collection userIds. 以 userId 为 key, 这样的缓存命中率更高, 存储的成本更小.
所以我们要实现对 Spring Cache 进行扩展. step3 中我们已经大致了解了 Spring Cache 的实现. 那么实现这个扩展的功能就是拆分 Collection userIds, 缓存命中的从缓存中获取, 没有命中的, 调用源方法.
然后扩展 Cache , CacheManage 重写 Cache 的查找缓存方法, 返回新的 CacheResult
CacheResult 就是新的缓存结果格式
然后扩展 CacheManager, 没什么重写, 就是自定义一种 manager 类型 为缓存指定新的 CacheManager
完整代码 https://github.com/FS1360472174/javaweb/tree/master/web/src/main/java/com/fs/web/cache
总结
本文主要介绍一种源码学习方法, 纯属抛砖引玉, 如果你有好的方法, 欢迎分享.
关注公众号 [方丈的寺院] , 第一时间收到文章的更新, 与方丈一起开始技术修行之路
来源: http://www.tuicool.com/articles/7VJrIbr