完成对spring cache文档的阅读

This commit is contained in:
2023-02-01 11:08:09 +08:00
parent 1362552f08
commit b894b5bbb6

View File

@@ -1,3 +1,22 @@
- [Spring Cache](#spring-cache)
- [Cache Abstract](#cache-abstract)
- [使用cache abstraction的要点](#使用cache-abstraction的要点)
- [缓存可能会存在的问题](#缓存可能会存在的问题)
- [基于声明式注解的缓存](#基于声明式注解的缓存)
- [@Cacheable](#cacheable)
- [默认的key生成](#默认的key生成)
- [自定义key生成的方式](#自定义key生成的方式)
- [sync caching](#sync-caching)
- [condition cache](#condition-cache)
- [@Cacheable和Optional](#cacheable和optional)
- [@CachePut](#cacheput)
- [@CacheEvict](#cacheevict)
- [@Caching](#caching)
- [@CacheConfig](#cacheconfig)
- [@EnableCaching](#enablecaching)
- [配置cache 存储](#配置cache-存储)
- [Cache Redis](#cache-redis)
# Spring Cache
## Cache Abstract
Cache针对java方法进行缓存当想要获取的信息在cache中可获取时可以从cache中进行获取从而降低了java方法的执行次数。
@@ -75,3 +94,73 @@ cache abstraction支持Optional类型如果Optional对象的value不为空
@Cacheable(cacheNames="book", condition="#name.length() < 32", unless="#result?.hardback")
public Optional<Book> findBook(String name)
```
### @CachePut
在不影响方法执行的情况下要将方法的执行结果更新到cache中可以使用@CachePut注解。标注了@CachePut的方法总会被执行并且执行的返回结果会被更新到cache中。
@CachePut注解支持和@Cacheable相同的参数,且@CachePut用于的是缓存的注入,而不应用于优化方法流程。
@CachePut的使用如下所示
```java
@CachePut(cacheNames="book", key="#isbn")
public Book updateBook(ISBN isbn, BookDescriptor descriptor)
```
> @CachePut注解和@Cacheable注解通常情况下不应用于同一方法上
### @CacheEvict
cache abstraction不仅支持缓存的注入而且支持缓存的淘汰该淘汰过程可以从缓存中移除过时或未使用的数据。
@CacheEvict注解具有allEntries属性将该属性标记为true可以逐出所有的缓存条目
```java
// 该场景下cache中的条目将会被清空
// 该场景下并不是依此逐出所有的key而是一次性清空所有缓存
@CacheEvict(cacheNames="books", allEntries=true)
public void loadBooks(InputStream batch)
```
可以为@CacheEvict注解指定beforeInvocation属性来指定该eviction行为是否应该在@CacheEvict方法被调用之前执行
- 默认情况下beforeInvocation属性的默认值为falseeviction操作在方法成功返回之后才执行如果该方法被cached或执行时抛出异常eviction操作不会执行
- 如果beforeInvocation属性被设置为true代表该eviction行为在方法被调用之前就会被执行
### @Caching
如果想要指定同一类型的多个注解(例如@CacheEvict或CachePut例如对不同的cachecondition和key expression不同。
@Caching注解允许对同一方法内嵌多个@Cacheable@CachePut@CacheEvict注解,使用示例如下:
```java
@Caching(evict = { @CacheEvict("primary"), @CacheEvict(cacheNames="secondary", key="#p0") })
public Book importBooks(String deposit, Date date)
```
### @CacheConfig
在使用cache注解时可能在同一个类中需要为所有cache operation指定相同的选项例如为类中所有的cache注解指定相同的cache name。此时可以通过一个class-level的@CacheConfig注解来指定类中所有cache operation的相同选项
```java
@CacheConfig("books")
public class BookRepositoryImpl implements BookRepository {
@Cacheable
public Book findBook(ISBN isbn) {...}
}
```
> 通过@CacheConfig注解指定的属性可以在cache operation中被覆盖
### @EnableCaching
想要在项目中启用所有的缓存注解,需要在一个@Configuration类上指定@EnableCaching注解
## 配置cache 存储
cache abstraction提供了一些存储集成选项。如果没有指定任何cache library那么spring boot会自动装配一个simple provider该provider使用concurrent map来进行缓存存储。当需要一个cache时cache provider会创建一个cache并返回给调用者。
### Cache Redis
如果redis在项目中配置并且可以获取那么spring boot会自动配置一个RedisCacheManager。可以在启动时配置其他cache通过在properties文件中指定spring.cache.cache-names属性并且cache的默认属性可以通过spring.cache.redis.*属性来进行配置:
```properties
spring.cache.cache-names=cache1,cache2
spring.cache.redis.time-to-live=10m
```
> 默认情况下对于不同的cache会添加一个key前缀继而如果两个不同的cache使用相同的key不会出现key冲突的情况
如果想要更细粒度的对cache进行配置可以通过如下方式进行配置
```java
@Configuration(proxyBeanMethods = false)
public class MyRedisCacheManagerConfiguration {
@Bean
public RedisCacheManagerBuilderCustomizer myRedisCacheManagerBuilderCustomizer() {
return (builder) -> builder
.withCacheConfiguration("cache1", RedisCacheConfiguration
.defaultCacheConfig().entryTtl(Duration.ofSeconds(10)))
.withCacheConfiguration("cache2", RedisCacheConfiguration
.defaultCacheConfig().entryTtl(Duration.ofMinutes(1)));
}
}
```