一、主要类&缓存注解
名称 | 解释 |
---|---|
@Cacheable | 主要针对方法配置,能够根据方法的请求参数对其进行缓存 |
@CachePut | 保证方法被调用,又希望结果被缓存。 与@Cacheable区别在于是否每次都调用方法,常用于更新 |
@CacheEvict | 清空缓存 |
@EnableCaching | 开启基于注解的缓存 |
@CacheConfig | 统一配置本类的缓存注解的属性 |
keyGenerator | 缓存数据时key生成策略 |
serialize | 缓存数据时value序列化策略 |
Cache | 缓存接口,定义缓存操作。实现有:RedisCache、EhCacheCache、ConcurrentMapCache等 |
CacheManager | 缓存管理器 |
核心注解参数
名称 | 解释 |
---|---|
value | 缓存的名称,在 spring 配置文件中定义 |
key | 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写, 如果不指定,则缺省按照方法的所有参数进行组合 例如: @Cacheable(value=”testcache”,key=”#id”) |
condition | 缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false, 只有为 true 才进行缓存/清除缓存 例如:@Cacheable(value=”testcache”,condition=”#userName.length()>2”) |
unless | 否定缓存。当条件结果为TRUE时,就不会缓存。 @Cacheable(value=”testcache”,unless=”#userName.length()>2”) |
allEntries (@CacheEvict ) | 是否清空所有缓存内容,缺省为 false,如果指定为 true, 则方法调用后将立即清空所有缓存 例如: @CachEvict(value=”testcache”,allEntries=true) |
beforeInvocation (@CacheEvict) | 是否在方法执行前就清空,缺省为 false,如果指定为 true, 则在方法还没有执行的时候就清空缓存,缺省情况下,如果方法 执行抛出异常,则不会清空缓存 例如: @CachEvict(value=”testcache”,beforeInvocation=true) |
二、开启缓存
1、在启动类上加注解 @EnableCaching
@SpringBootApplication
@EnableCaching
public class RedisCacheApplication {
public static void main(String[] args) {
SpringApplication.run(RedisCacheApplication.class, args);
}
}
2、EnableCaching
完成了这些配置之后,Spring Boot就会自动帮我们在后台配置一个RedisCacheManager,相关的配置是在RedisCacheConfiguration类中完成的。
@Configuration
@ConditionalOnClass(RedisConnectionFactory.class)
@AutoConfigureAfter(RedisAutoConfiguration.class)
@ConditionalOnBean(RedisConnectionFactory.class)
@ConditionalOnMissingBean(CacheManager.class)
@Conditional(CacheCondition.class)
class RedisCacheConfiguration {
@Bean
public RedisCacheManager cacheManager(RedisConnectionFactory redisConnectionFactory, ResourceLoader resourceLoader) {
RedisCacheManagerBuilder builder = RedisCacheManager.builder(redisConnectionFactory).cacheDefaults(determineConfiguration(resourceLoader.getClassLoader()));
List<String> cacheNames = this.cacheProperties.getCacheNames();
if (!cacheNames.isEmpty()) {
builder.initialCacheNames(new LinkedHashSet<>(cacheNames));
}
return this.customizerInvoker.customize(builder.build());
}
}
三、添加@Cacheable
1、作用
表示将一个方法的返回值缓存起来,一般用于查询方法,默认情况下,缓存的key就是方法的参数,缓存的value就是方法的返回值。执行过程
- 先查询是否已经有缓存
- 有会使用缓存
- 没有则会执行方法并缓存
2、源代码
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Cacheable {
@AliasFor("cacheNames")
String[] value() default {};
@AliasFor("value")
String[] cacheNames() default {};
String key() default "";
String keyGenerator() default "";
String cacheManager() default "";
String cacheResolver() default "";
String condition() default "";
String unless() default "";
boolean sync() default false;
}
2、属性说明
属性说明 | 说明 |
---|---|
String key() | key的生成器。可以是spEL表达式。默认情况下,缓存的key就是方法的参数 |
String[] value() | 同cacheNames |
String[] cacheNames() | 必要参数,指定一个或多个Cache名字 |
String keyGenerator() | key的生成器。key/keyGenerator二选一使用 |
String cacheManager() | 指定缓存管理器 |
String cacheResolver() | 指定获取解析器 |
String condition() | 条件符合则缓存 |
String unless() | 条件符合则不缓存 |
boolean sync() | 是否使用异步模式 |
4、栗子
@RestController
public class CacheController {
// @Cacheable(cacheNames = "index",key = "#name")
@RequestMapping("/")
@Cacheable(cacheNames = "index", key = ("targetClass.getName() + '.'+methodName"))
public String index() {
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
}
}
5、key自定义策略
当有多个参数时,默认就使用多个参数来做key,如果只需要其中某一个参数做key,则可以在@Cacheable注解中,通过key属性来指定key,如上代码就表示只使用id作为缓存的key,如果对key有复杂的要求,可以自定义keyGenerator。
当然,Spring Cache 中提供了root对象,可以在不定义keyGenerator的情况下实现一些复杂的效果
#root可以省略
属性名称 | 描述 | 示例 |
---|---|---|
methodName | 当前方法名 | #root.methodName |
method | 当前方法 | #root.method.name |
target | 当前被调用的对象 | #root.target |
targetClass | 当前被调用的对象的class | #root.targetClass |
args | 当前方法参数组成的数组 | #root.args[0] |
caches | 当前被调用的方法使用的Cache | #root.caches[0].name |
@Bean
public KeyGenerator myKeyGenerator(){
return new KeyGenerator(){
@Override
public Object generate(Object target, Method method, Object... params) {
StringBuilder sb = new StringBuilder();
sb.append(target.getClass().getName());
sb.append(method.getName());
for (Object obj : params) {
sb.append(obj.toString());
}
return sb.toString();
}
};
}
四、更新@CachePut
1、作用
主要针对方法配置,能够根据方法的请求参数对其结果进行缓存,和 @Cacheable
不同的是,它每次都会触发真实方法的调用 。简单来说就是用户更新缓存数据。但需要注意的是该注解的value
和 key
必须与要更新的缓存相同,也就是与@Cacheable
相同
2、源码
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface CachePut {
@AliasFor("cacheNames")
String[] value() default {};
@AliasFor("value")
String[] cacheNames() default {};
String key() default "";
String keyGenerator() default "";
String cacheManager() default "";
String unless() default "";
}
3、属性说明
同@Cacheable
4、栗子
@CachePut(value = "index", key = ("targetClass.getName() + '.'+methodName"))
public String updateDate() {
return "更新数据";
}
5、注意
- key和value一定要和查询的(@Cacheable)一样
五、删除@CacheEvict
1、作用
主要针对方法配置,能够根据一定的条件对缓存进行清空 。
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface CacheEvict {
// ...其它属性同上
boolean allEntries() default false;
boolean beforeInvocation() default false;
}
2、属性说明
属性 | 解释 | 示例 |
---|---|---|
allEntries | 是否清空所有缓存内容,缺省为 false,如果指定为 true,则方法调用后将立即清空所有缓存 | @CachEvict(value="index",allEntries=true) |
beforeInvocation | 是否在方法执行前就清空,缺省为 false,如果指定为 true,则在方法还没有执行的时候就清空缓存,缺省情况下,如果方法执行抛出异常,则不会清空缓存 | @CachEvict(value="index",beforeInvocation=true) |
六、配置@CacheConfig
1、作用
这个注解是用于在同一个类中共享一些基础的cache配置的
一个类级别的注解,允许共享缓存的名称、KeyGenerator、CacheManager 和CacheResolver。
该操作会被覆盖。
七、组合@Caching
1、作用
有时候我们可能组合多个Cache注解使用,此时就需要@Caching组合多个注解标签了。
2、源码
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Caching {
Cacheable[] cacheable() default {};
CachePut[] put() default {};
CacheEvict[] evict() default {};
}
网友评论