SpringBoot中缓存的使⽤
⼀、缓存使⽤
1.使⽤缓存储存数据@Cacheable
1. 在启动类上加开启缓存的注解
//开启基于注解的缓存
@EnableCaching
2. 在要使⽤缓存的⽅法上标注缓存注解,缓存⽅法的返回值
//将⽅法的运⾏结果进⾏缓存。以后再有相同参数的查询时,直接从缓存中获取,不⽤调⽅法
@Cacheable
Cacheable的⼏个属性:
1. cacheNames/value:指定缓存组件的名字。
也就是指定缓存在哪⼉个Cache中,可以同时缓存在多个Cache中(可以传⼀个数组:{"cache1","cache2"})
2. key:指定缓存数据使⽤的key。
默认是⽅法参数的值?
还可以使⽤SpEL语法来指定key为⽅法名、调⽤⽅法的对象、⽅法参数、⽅法返回值等等。
如指定key="⽅法名[参数]"对应的SpEL表达式为#hodName+'['+#id+']'其中root对象就表⽰根对象,⾥⾯可以获取到调⽤信息、⽅法信息、参数等等。
@Cacheable的key是不能⽤ #result 的,因为@Cacheable是先缓存再调⽤⽅法,⽽#result是⽅法调⽤完成后才会有
3. keyGenerator:指定key的⽣成器;值为⾃定义的key⽣成器组件的id(id为注⼊容器时的标识@Bean(“id”))。
key和keyGenerator属性不能同时存在,⼆选⼀使⽤。
4. cacheManager:指定缓存管理器。当不同的缓存管理器中有相同name的Cache时,⽤这个属性指定缓存管理器。
也可以通过cacheResolver指定获取解析器。
5. condition:指定缓存的条件,当条件符合时才缓存。例:condition = "#id>0" and 连接多个条件
6. unless:指定不缓存的条件,当条件符合时不缓存。例:unless = "#result == null"
7. sync:是否使⽤异步模式。默认为false不使⽤异步。异步模式下unless不⽣效。
注解中key属性的SpEL语法
2.更新缓存数据@CachePut
⼀般⽤于修改了数据库的某个数据,同时更新缓存的场景。
//value是指定缓存组件,key要和⽬标key保持⼀致
@CachePut(value ="emp",key ="#result.id")
运⾏机制
1. 先调⽤⽬标⽅法
2. 将⽬标⽅法的结果缓存起来
3.清除缓存数据@CacheEvict
@CacheEvict()
可选属性:
1. key:指定要清除的key
2. allEntries = true:指定清除这个缓存中所有的数据
3. beforeInvocation = false:缓存的清除是否在⽅法之前执⾏。默认为false。
如果为false,⽅法出现异常缓存就不会清除
如果为true,⽆论⽅法是否异常缓存都会清除
@CacheEvict:缓存清除
beforeInvocation = true:代表清除缓存操作是在⽅法运⾏之前执⾏,⽆论⽅法是否出现异常,缓存都清除
4.组合注解@Caching
@Caching 注解相当于@Cacheable、@CachePut、@CacheEvict三个注解的组合注解
//Caching源码
public @interface Caching {
Cacheable[]cacheable()default{};
CachePut[]put()default{};
CacheEvict[]evict()default{};
}
//在⽅法上定义复杂的缓存规则
@Caching(
cacheable ={
@Cacheable(/*value="emp",*/key ="#lastName")
},
put ={
@CachePut(/*value="emp",*/key ="#result.id"),
@CachePut(/*value="emp",*/key ="#ail")
}
)
public Employee getEmpByLastName(String lastName){
EmpByLastName(lastName);
}
注意:当Caching中指定了put属性时,每次查询都会执⾏⽅法,因为@ChchePut的执⾏顺序是先执⾏⽅法再存⼊缓存。
5.缓存配置@CacheConfig
@CacheConfig配置在类上,指定当前类的公共配置
@CacheConfig(cacheNames="emp")
//@CacheConfig源码
/
/通过源码可以看出,可抽取的属性有:cacheNames组件名称、keyGenerator⽣成器、cacheManager组件管理器、cacheResolver解析器
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CacheConfig {
String[]cacheNames()default{};
String keyGenerator()default"";
String cacheManager()default"";
String cacheResolver()default"";
}
⼆、缓存规范
1.JSR107缓存规范
Java Caching定义了5个核⼼接⼝:
springboot结构1. CachingProvider: 定义了创建、配置、获取、管理和控制多个CacheManager。⼀个应⽤可以在运⾏期访问多个
CachingProvider。
2. CacheManager: 定义了创建、配置、获取、管理和控制多个唯⼀命名的Cache,这些Cache存在于CacheManager的上下⽂中。
⼀个CacheManager仅被⼀个CachingProvider所拥有。
3. Cache: 是⼀个类似Map的数据结构并临时存储以Key为索引的值。⼀个Cache仅被⼀个CacheManager所拥有。
4. Entry: 是⼀个存储在Cache中的key-value对。
5. Expiry: 每⼀个存储在Cache中的条⽬有⼀个定义的有效期。⼀旦超过这个时间,条⽬为过期的状态。⼀旦过期,条⽬将不可访问、更
新和删除。缓存有效期可以通过ExpiryPolicy设置。
结构图:
2.Spring缓存抽象
1.Spring的缓存抽象保留了CacheManager和Cache的概念
1. Cache接⼝为缓存的组件规范定义,包含缓存的各种操作集合;
2. Cache接⼝下Spring提供了各种xxxCache的实现;如RedisCache,EhCacheCache , ConcurrentMapCache等;
2.Spring缓存使⽤
每次调⽤需要缓存功能的⽅法时,Spring会检查检查指定参数的指定的⽬标⽅法是否已经被调⽤过;如果有就直接从缓存中获取⽅法调⽤后的结果,如果没有就调⽤⽅法并缓存结果后返回给⽤户。下次调⽤直接从缓存中获取。
使⽤Spring缓存抽象时我们需要关注以下两点:
1. 确定⽅法需要被缓存以及他们的缓存策略
2. 从缓存中读取之前缓存存储的数据
3.⼏个重要的概念&缓存注解
概念/注解详情
Cache缓存接⼝,定义缓存操作。实现有:RedisCache、EhCacheCache、ConcurrentMapCache等CacheManager缓存管理器,管理各种缓存(Cache)组件
@Cacheable主要针对查询⽅法配置,如果是第⼀次查询,能够根据⽅法的请求参数对其结果进⾏缓存,之后相同请求参数的请求将直接⾛缓存@CacheEvict清空缓存,常⽤于删除⽅法之上
@CachePut保证⽅法被调⽤,⼜希望结果被缓存,⽤于更新缓存
概念/注解详情
@EnableCaching开启基于注解的缓存
keyGenerator缓存数据时key⽣成策略
serialize缓存数据时value序列化策略
三、缓存原理
1.@Cacheable注解的运⾏原理
1.⾃动配置原理
1. 缓存的⾃动配置类:CacheAutoConfiguration
2. 缓存的配置类-----各种缓存对应的配置类
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.GuavaCacheConfiguration
org.springframework.boot.autoconfigure.cache.SimpleCacheConfiguration【默认】
org.springframework.boot.autoconfigure.cache.NoOpCacheConfiguration
3. 默认⽣效的配置类:SimpleCacheConfiguration
4. SimpleCacheConfiguration给容器中注册了⼀个CacheManager:ConcurrentMapCacheManager
5. ConcurrentMapCacheManager可以获取和创建ConcurrentMapCache类型的缓存组件;他的作⽤将数据保存在ConcurrentMap
中;
2.@Cacheable运⾏流程
1. ⽅法运⾏之前,先去CacheManager中查询Cache(缓存组件),按照cacheNames指定的名字获取(CacheManager先获取相应
的缓存),第⼀次获取缓存时,如果没有Cache组件则会⾃动创建。
2. 拿到Cache后,根据⼀个key去Cache中查缓存的内容
key是按照某种策略⽣成的
默认是使⽤keyGenerator接⼝的SimpleKeyGenerator实现类⽣成key
SimpleKeyGenerator⽣成key的默认策略:
1. 如果没有参数;key=new SimpleKey();
2. 如果有⼀个参数:key=参数的值
3. 如果有多个参数:key=new SimpleKey(params);
3. 没有查到缓存就调⽤⽬标⽅法
4. 将⽬标⽅法返回的结果,放进缓存中
总结:
@Cacheable标注⽅法执⾏流程
1. 执⾏之前先来检查缓存中有没有这个数据,默认按照参数的值作为key去查询缓存,
2. 如果没有就运⾏⽅法并将结果放⼊缓存
3. 再来调⽤就可以直接使⽤缓存中的数据
核⼼:
1.默认使⽤CacheManager【ConcurrentMapCacheManager缓存管理器】按照名字得到Cache【ConcurrentMapCache类型】
组件
2.key使⽤keyGenerator⽣成的,默认是SimpleKeyGenerator
四、Redis
1.使⽤Redis做Cache实现
1. 导⼊Redis依赖(Jedis)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
2. 指定Redis的主机地址
3. 引⼊RedisTemplate
@Autowired
StringRedisTemplate stringRedisTemplate;//操作k-v都是字符串的
@Autowired
RedisTemplate redisTemplate;//k-v都是对象的
//Redis常见的五⼤数据类型
//String(字符串)、List(列表)、Set(集合)、Hash(散列)、ZSet(有序集合)
stringRedisTemplate.opsForValue()[String(字符串)]
stringRedisTemplate.opsForList()[List(列表)]
stringRedisTemplate.opsForSet()[Set(集合)]
stringRedisTemplate.opsForHash()[Hash(散列)]
stringRedisTemplate.opsForZSet()[ZSet(有序集合)]
2.操作实例
//String
@Test
public void test01(){
//给redis中保存数据
stringRedisTemplate.opsForValue().append("msg","hello");
//获取
String msg = stringRedisTemplate.opsForValue().get("msg");
System.out.println(msg);
//左push
stringRedisTemplate.opsForList().leftPush("mylist","1");
stringRedisTemplate.opsForList().leftPush("mylist","2");
...
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论