Springboot缓存
-
Spring缓存抽象
-
重要概念以及缓存注解
-
Cache:缓存接口,定义缓存操作,实现又:RedisCache,EhCacheCache,ConcurrentMapCache等
-
CacheManager:缓存管理器,管理各种缓存组件
-
@Cacheable:修饰方法,能够根据方法的请求参数和返回结果进行缓存
-
@CacheEvict:修饰方法,清空缓存,例如从数据库删除某个用户,那就需要把相应的缓存也删除掉
-
@CachePut:修饰方法,调用函数,更新缓存
-
@Cacheable一旦缓存命中,就不再调用修饰的函数了
-
@CachePut一定会调用函数,并把值放到缓存,常用于更新操作,先调用函数,在更新缓存
-
-
@EnableCaching:开启基于注解的缓存模式
-
keyGenerator:缓存数据时key的生成策略
-
serialize:缓存数据时value序列化策略
-
-
搭建环境
-
引入包
-
< dependency>
-
< groupId > org.springframework.boot </ groupId >
-
< artifactId > spring-boot-starter-cache </ artifactId >
-
</ dependency >
-
-
使用缓存@Cacheablepublic String getUser( int id){System. out .println( " 缓存未命中 " );return "zhangsan" ;}
-
开启基于注解的缓存
-
-
-
使用缓存
-
-
-
@Cacheable@Caching(cacheable={ @Cacheable (), @Cacheable ()},put={},evict = {})
-
属性
-
cacheNames/value :数组,缓存名字,因为缓存管理器下有许多缓存,所以这个指定从哪个缓存中查找数据,或者将数据存入哪个缓存中,可以将一份数据存到多个缓存
-
@Cacheable(cacheNames="emp")
-
-
key:存缓存或者查找缓存value时用的键,支持spel表达式。默认key为参数的值
-
-
@Cacheable的key不能用#result
-
-
keyGenerator:key的生成器,可以指定key生成器的组件id,key和 keyGenerator两个属性二选一@Configurationpublic class CacheAutoConfiguration{@Bean ( "myKeyGenerator" )public KeyGenerator keyGenerator(){return new KeyGenerator() {@Overridepublic Object generate(Object target, Method method, Object... params) {return "hahaha" ;}}}}
-
自定义 keyGenerator
-
使用自定义的 keyGenerator
-
@Cacheable (cacheNames = "emp" , keyGenerator = "myKeyGenerator" )
-
-
-
cacheManager:指定从哪个缓存管理器中拿到缓存,
-
cacheResolver:指定寻找 cacheManager的策略, cacheResolver与 cacheManager二选一
-
condition:可以使用spel表达式,满足条件才缓存
-
unless:满足unless条件,则不缓存,可以获取到结果进行判断
-
@Cacheable(unless="#result == null")
-
-
sync:是否使用异步模式,默认false.意思是。在put数据时,是异步还是同步
-
-
原理
-
自动配置类: CacheAutoConfiguration
-
Import选择器: CacheConfigurationImportSelector
-
org.springframework.boot.autoconfigure.cache.GenericCacheConfiguration
-
org.springframework.boot.autoconfigure.cache.JCacheCacheConfiguration
-
org.springframework.boot.autoconfigure.cache.EhCacheCacheConfiguration
-
org.springframework.boot.autoconfigure.cache.HazelcastCacheConfiguration
-
org.springframework.boot.autoconfigure.cache.InfinispanCacheConfiguration
-
org.springframework.boot.autoconfigure.cache.CouchbaseCacheConfiguration
-
org.springframework.boot.autoconfigure.cache.RedisCacheConfiguration
-
org.springframework.boot.autoconfigure.cache.CaffeineCacheConfiguration
-
org.springframework.boot.autoconfigure.cache.SimpleCacheConfiguration
-
org.springframework.boot.autoconfigure.cache.NoOpCacheConfiguration
-
-
哪个配置生效呢?
-
每个CacheConfiguration上面都用注解标识了生效条件
-
SimpleCacheConfiguration这个有可能生效
-
-
SimpleCacheConfiguration给容器中注入了一个CacheManager( ConcurrentMapCacheManager)的bean
-
ConcurrentMapCacheManager维护了一个Map<String, ConcurrentMapCache>,String为缓存的名字
-
-
ConcurrentMapCacheManager可以获取和创建 ConcurrentMapCache组件,并将数据放到 ConcurrentMapCache中
-
ConcurrentMapCache就是一个类,属性有name和 ConcurrentMap
-
-
整个流程
-
-
-
@CachePut
-
先调用函数在更新缓存
-
注意点
-
@Cacheable添加缓存
-
@Cacheable(cacheNames = "emp", keyGenerator = "myKeyGenerator")
-
public String getUser( int id){
-
-
@ CachePut添加缓存
-
@CachePut (cacheNames = "emp" )
-
public Employee update(Employee emp){
-
-
这两个缓存的key的生成可能不一杨,可能会导致他们更新的缓存原本应该是同一个,但是却由于生成key不一样,导致缓存更新错误
-
-
-
@CacheEvict
-
key:指定要清除的key
-
allEntries=true:清除缓存中的所有数据,默认false
-
beforeInvocation=true:实在方法执行之前清除缓存,还是在方法执行之后清除缓存,默认为false,
-
如果在方法执行之后清除缓存,一旦方法出现异常,那么缓存不会被清除
-
-
-
@Caching可以使用组合注解
-
@CacheConfig修饰类,可以将 Cacheable, CachePut, CacheEvict的公共属性提取出来
-
-
-
整合redis使用缓存
-
引入依赖
-
<!-- springboot整合redis的starter- ->
-
< dependency>
-
< groupId > org.springframework.boot </ groupId >
-
< artifactId > spring-boot-starter-data-redis </ artifactId >
-
</ dependency >
-
<!-- redis如果要使用连接池技术,需要依赖这个包- ->
-
< dependency >
-
< artifactId > commons-pool2 </ artifactId >
-
</ dependency >
-
<!-- 由于我们需要更改对象序列化为json存到redis中,需要这个包 -->
-
< dependency >
-
< groupId > com.fasterxml.jackson.core </ groupId >
-
< artifactId > jackson-core </ artifactId >
-
< version > 2.9.8 </ version >
-
</ dependency >
-
<!-- 从redis读取数据,反序列化为对象时,绑定数据需要这个包 -->
-
< dependency >
-
< groupId > com.fasterxml.jackson.core </ groupId >
-
< artifactId > jackson-databind </ artifactId >
-
< version > 2.9.8 </ version >
-
</ dependency >
-
-
配置redis连接池
-
spring:
-
redis :
-
host : 127.0.0.1
-
port : 6379
-
database : 0
-
lettuce :
-
pool :
-
# 连接池最大连接数 默认 8 ,负数表示没有限制
-
max-active : 20
-
# 连接池中的最大空闲连接 默认 8
-
max-idle : 10
-
# 连接池最大阻塞等待时间(使用负值表示没有限制) 默认 -1
-
max-wait : 1000
-
-
-
timeout : 10000
-
-
-
-
修改cacheManager的默认配置
-
public CacheManager cacheManager(LettuceConnectionFactory redisConnectionFactory) {// 初始化一个 RedisCacheWriterRedisCacheWriter redisCacheWriter = RedisCacheWriter. nonLockingRedisCacheWriter (redisConnectionFactory);// 设置 CacheManager 的值序列化方式为 json 序列化Jackson2JsonRedisSerializer<Person> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Person. class );RedisSerializationContext.SerializationPair<Person> pair = RedisSerializationContext.SerializationPair. fromSerializer (jackson2JsonRedisSerializer);RedisCacheConfiguration defaultCacheConfig= RedisCacheConfiguration. defaultCacheConfig ().serializeValuesWith(pair).entryTtl(Duration. ofSeconds ( 30 )) // 设置默认超过期时间是 30 秒.disableCachingNullValues();// 初始化 RedisCacheManagerreturn new RedisCacheManager(redisCacheWriter, defaultCacheConfig);}
-
使用注解即可
-
开启缓存@EnableCaching
-
在相应方法上添加注解
-
@Cacheable(cacheNames = "statuschecker")
-
public Person request( int id){
-
System. out .println( "Cache 未命中 " );
-
return new Person( "www" , 24 );
-
-
}
-
-
-