Spring Cache的基础
Spring Cache
文章目录
- Spring Cache
- 一、认识`Spring Cache`
- 二、Spring Cache 抽象
- 2.1 缓存注解
- (1)`@Cacheable`
- (2)`@CachePut`
- (4)`@Caching`
- (5) `@CacheConfig` 类级别的缓存
- 三、实践经验
一、认识
Spring Cache
第一步:配置缓存管理
>
【Spring Cache的基础】第二步:使用缓存
@Cacheable(cacheNames = "users")
@Override
public User getUserById(String userId) {
System.out.println("real query user." + userId);
return getFromDB(userId);
}private User getFromDB(String userId){
System.out.println("real querying db..." + userId);
return new User.Builder().userId(userId).email("someone@gmail.com").builder();
}
二、Spring Cache 抽象 只有使用public定义的方法才可以被缓存。
缓存的本质就是键/值对集合。在默认情况下,缓存抽象使用方法签名及参数值作为一个键值,并将该键与方法调用的结果组成键/值对。
2.1 缓存注解
(1)
@Cacheable
Spring首先在缓存中查找数据,如果没有则执行方法并缓存结果,然后返回数据
- 缓存名必须提供;可以使用引号、Value或者cacheNames属性来定义名称
@Cacheable(cacheNames = "users") @Cacheable(values = "users") @Cacheable(cacheNames = {"cache01","cache02"})
- 键生成器
默认情况下,缓存抽象使用方法签名及参数值作为一个键值,并将键与方法调用的结果组成键/值对。
1)可以使用SpEL指定自定义键
@Cacheable(cacheNames = "users", key = "#user.userCode") public User getUserByUser(User user) { System.out.println("real query user." + user.getUserCode()); return getFromDB(user.getUserId()); }
2)可以通过实现org.springframework.cache.interceptor.KeyGenerator
接口来定义个性化的Key生成器
@Cacheable(cacheNames = "users", keyGenerator = "myKeyGenerator")
3)带条件缓存
@Cacheable(cacheNames = "users", key = "#user.userCode", condition = "#user.age >= 12")
@CachePut
首先执行方法,然后将返回值放入缓存。当希望使用方法返回值更新缓存时,便可以选择这种方法。####(3)
@CacheEvict
负责从给定的缓存中移除一个值。默认情况下,
@CacheEvict
注解在方法调用之后运行。@allEntries
属性 定义了是否移除缓存的所有条目,默认不移除这些条目;@beforeInvocation
属性定义了在调用方法之前还是之后完成移除操作。@CacheEvict(cacheNames = "users", allEntries = true, beforeInvocation = true)
(4)
@Caching
@Caching
是一个组注解,可以为一个方法定义提供基于@Cacheable
、@CacheEvict
、@CachePut
注解的数组@Caching(cacheable = {@Cacheable(value = "https://www.it610.com/article/members", condition = "#obj instanceof T(com.hef.domain.Member)"),
@Cacheable(value = "https://www.it610.com/article/visitors", condition = "#obj instanceof T(com.hef.domain.Visitor)")})
(5)
@CacheConfig
类级别的缓存 如果一个类中需要缓存的方法注解属性都相似,可以在类上通过@CacheConfig
配置缓存,在方法上用@Cacheable
标记。三、实践经验 基于Proxy的Spring AOP带来的内部调用问题。
如果对象的方法是内部调用(this)而不是外部引用,则会导致代理失效,那么切面就失效,也就是说上面定义的各种注解,包括
@Cacheable、@CachePut、@CacheEvict
都会失效
public User getUserByUser02(User user) {
return getUserByUser(user);
}@Cacheable(cacheNames = "users", key = "#user.userCode")
public User getUserByUser(User user) {
System.out.println("real query user." + user.getUserCode());
return getFromDB(user.getUserId());
}
在方法
getUserByUser02()
上调用getUserByUser()
,发生了内部调用(this),所以没有使用代理类,导致Spring Cache失效。要避免这个问题,就要避免方法的内部调用,或者避免使用基于代理的AOP模式,也可以使用基于AspectJ的AOP模式来解决这个问题。推荐阅读
- 热闹中的孤独
- JAVA(抽象类与接口的区别&重载与重写&内存泄漏)
- 放屁有这三个特征的,请注意啦!这说明你的身体毒素太多
- 一个人的旅行,三亚
- 布丽吉特,人生绝对的赢家
- 慢慢的美丽
- 尽力
- 一个小故事,我的思考。
- 家乡的那条小河
- 《真与假的困惑》???|《真与假的困惑》??? ——致良知是一种伟大的力量