上图简单绘制了Spring中定义的Cache接口和caffeine中定义的Cache接口。
Spring的Cache定义了极其通用的方法,包括获取实例名、根据缓存项的key获取、更新和移除缓存项。
Spring并没有限定缓存所使用的具体存储结构,不管使用哪一种存储结构,在Spring的Cache中都以nativeCache进行表示,注意它是Object类型的。
caffeine的Cache接口,就是caffeine对nativeCache的又一层抽象,它提供了asMap方法可以对缓存项进行遍历。
使用缓存在上文中,我们已经简单演示了如何使用缓存。除了获取缓存之外,我们几乎没有任何额外的代码,只是在合适的地方,添加了注解,就添加了缓存的功能。
所以在日常开发中,如果我们意识到某个操作可能会有很大开销,不妨把它移到一个独立的组件,实现之后根据具体情况考虑是否为它添加缓存。
注意:如果缓存的方法是组件内部调用的,可能没有缓存的效果。
比如,上文中的QueryService的query方法,是由QueryController调用的,缓存生效了。如果该方法由QueryService自身的其他方法调用,缓存无效。
在上文的demo中,我们已经使用了一些基本的功能,还有一些常用的功能如下:
指定key构建规则在上文中,我们使用默认的规则来构建缓存项的key,即以参数keyWord作为key。
在必要的情况下,我们可以指定key构建的规则,使用spring el表达式:
@Cacheable(cacheNames="books", key="#isbn") public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed) @Cacheable(cacheNames="books", key="#isbn.rawNumber") public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed) @Cacheable(cacheNames="books", key="T(someType).hash(#isbn)") public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)第一个实例,我们使用三个参数中的其中一个来构建key。
第二个实例,我们使用参数内部的field来构建key。
第三个实例,我们使用静态方法来生成key。
更多内容可以参考。
有选择的cache上文demo中我们使用unless属性对方法返回的结果进行判断,当返回结果满足一定条件时才进行缓存。
另外,我们还可以使用condition属性对方法的参数进行判断:
@Cacheable(cacheNames="book", condition="#name.length() < 32") public Book findBook(String name)上述代码表示,只有当参数的长度小于32时,我们才会缓存。
更多内容可以参考。
扩展阅读
Spring官方demo
这里提供了使用默认缓存的demo,内容更加简单,适合对spring-boot不熟悉的读者。
这里有对如何使用cache的详细介绍,比如如何主动更新缓存、移除缓存,都是本demo中没有的内容。