Spring – 缓存注解
Spring缓存抽象概述
Spring框架自身并没有实现缓存解决方案,但是从3.1开始定义了org.springframework.cache.Cache和org.springframework.cache.CacheManager接口,提供对缓存功能的声明,能够与多种流行的缓存实现集成。
Cache接口为缓存的组件规范定义,包含缓存的各种操作集合;
Cache接口下Spring提供了各种xxxCache的实现:如RedisCache,EhCacheCache , ConcurrentMapCache等;
CacheManager接口为缓存管理器规范,简单来说就是用于存放cache,Spring默认也提供了一些列管理器的实现。
Spring缓存抽象提供了5个注解用来声明缓存规则:
@Cacheable:能够根据方法的请求参数对其结果进行缓存,多用于查询
@CachePut: 执行方法,并缓存结果
@CacheEvict:清空缓存
@Caching:能够同时应用多个缓存注解功能
@CacheConfig: 用于抽取缓存的公共配置(类级别)
以上5个注解除了@CacheConfig注解是类级别的注解,其余4个注解在类和方法上均可以使用,作用在类上表示对该类下所有方法生效,作用的方法上只对该方法生效,且只能用于public修饰的符方法,protected或者private修饰的方法不适用。
@Cacheable注解
@Cacheable注解的作用是Spring在调用该方法之前,首先在缓存中查找方法的返回值,默认的key是根据参数值生成,如果存在,直接返回缓存中的值,否则执行该方法,并将返回值保存到缓存中
@Cacheable运行流程:
1.方法运行之前,先去查询Cache(缓存组件),按照cacheNames指定的名字获取;
(CacheManager先获取相应的缓存),第一次获取缓存如果没有Cache组件会自动创建。
2.去Cache中查找缓存的内容,使用一个key,默认就是方法的参数值;
key是按照某种策略生成的;默认是使用keyGenerator生成的,
Spring默认加载的是SimpleCacheManage,SimpleKeyGenerator生成key的默认策略是:
如果没有参数;key=new SimpleKey()
如果有一个参数:key=参数的值
如果有多个参数:key=new SimpleKey(params)
3.没有查到缓存就调用目标方法;
4.将目标方法返回的结果,放进缓存中
@Cacheable属性说明:
1.acheNames/value:该属性值必须提供,指定缓存组件的名字,将方法的返回结果放在哪个缓存中,是数组的方式,可以指定多个缓存;
如:cacheNames = "product"或者cacheNames = {"product1","product2"}
2.key:缓存数据使用的key,不指定key则默认是使用方法参数的值该属性值支持SpEL表达式
3.cacheManager:指定缓存管理器;或者cacheResolver指定获取解析器
4.condition:指定符合条件的情况下才缓存
5.unless:否定缓存;当unless指定的条件为true,方法的返回值就不会被缓存;可以获取到结果进行判断
unless = "#result == null"
unless = "#a0==2":如果第一个参数的值是2,结果不缓存;
6.sync:是否使用异步模式
使用示例:
@Cacheable(cacheNames = "product")// 默认key为参数,多个参数SimpleKey [arg1,arg2]
//@Cacheable(cacheNames = "product",key = "#root.methodName+'['+#id+']'")
//@Cacheable(cacheNames = "product",keyGenerator = "myKeyGenerator")
//@Cacheable(cacheNames = "product",key = "#root.methodName+'['+#id+']'",condition="#a0>10",unless = "#a0==11") //带条件的缓存满足condition=true缓存,满足unless=true则不缓存
public Product getProductById(Long id){
Product product =productMapper.getProductById(id);
System.out.println(product);
return product;
}
//指定key属性值
@Cacheable(cacheNames ="product", key="#id") //”#+参数名”的形式,直接使用参数名
//或者
//@Cacheable(cacheNames ="product", key="#a0") //”#a+参数位置”的形式
public Product getProductById(long id) {
xxxx
}
@Cacheable(cacheNames ="product", key="# productcondition.productId")
//或者
//@Cacheable(cacheNames ="product", key="#a0.productId")
public Product getProduct (Product productcondition) {
xxxx
}
自定义Key生成器
除了通过SPEL表达式之外,还可以通过自定义key生成器的方式,Spring缓存模块提供了org.springframework.cache.interceptor.KeyGenerator接口用于缓存key的生成声明,因此我们可以自定义一个MyKeyGenerator类并实现了KeyGenerator接口 ,使用如下:
@Configuration
public class MyCacheConfig { @Bean("myKeyGenerator")
public KeyGenerator keyGenerator(){
return new KeyGenerator(){ @Override
public Object generate(Object target, Method method, Object... params) {
return method.getName()+"["+ Arrays.asList(params).toString()+"]";
}
};
}
}
该方法测试用,关于缓存key的生成方式,网上有很多种策略。
使用时只需要修改注解的key属性即可:
@Cacheable(cacheNames = "product",keyGenerator = "myKeyGenerator")
@CachePut
@CachePut注解的作用简单的说一句话:既调用方法,又缓存数据。@cachePut和@Cacheable两个注解都可以用于填充缓存,但使用上略有点差异,@Cacheable注解的执行流程是先在按key在缓存中查找,存在则返回,不存在则执行目标方法,并缓存目标方法的结果。而@CachePut并不会检查缓存,总是先执行目标方法,并将目标方法的结果保存到缓存中。实际中比如执行到更新操作时,则希望将最新的数据更新到缓存,如果该方法返回异常,将不再执行保存缓存的逻辑。
@CachePut属性说明
@CachePut注解属性与@CachePut类似,并没有增加其他属性
使用示例:
@CachePut(value="product",key = "#result.productId",condition = "#result!=null")
public Product updateProduct(Product product){
int count = productMapper.updateProduct(product);
System.out.println("影响行数:"+count);
if(count>0){
return product;
}else{
return null;
}
}
@CacheEvict注解
该注解的作用根据指定的key或者是allEntries属性值移除缓存中特性的键值对。
@CacheEvict属性说明
与@Cacheable相比@CacheEvict注解提供了另外两个属性:
- allEntries:表示是否清空所有缓存内容,默认false,如果该值为true则清空指定cacheNames缓存块下所有内容,如果指定了allEntries为true,那么再zhidingkey值将没有意义 
- beforeInvocation:是否在执行方法前请空缓存,默认值为false,如果该值为true则在调用目标方法前执行清空缓存,为false的情况下,如果目标方法抛出异常,则不再执行清空缓存逻辑 
示例:
//@CacheEvict(value="product",key="#id")
//@CacheEvict(value="product",allEntries = true) //清楚所有缓存
@CacheEvict(value="product",allEntries = true,beforeInvocation = true) //清楚所有缓存
public boolean deleteProductById(Long id) {
productMapper.deleteProductById(id);
return true;
}
@Caching注解
该注解是一个分组注解,作用是可以同时应用多个其他注解,该注解提供了3个属性cacheable,put,evict分别用于组合@Cacheable、@CachePut、@CacheEvict三个注解
使用示例:
@Caching(
cacheable = {@Cacheable(value="product",key="#productName")},
put = {
@CachePut(value="product",key="#result.productId"),
@CachePut(value="product",key="#result.productName")
}
)
public Product getProductByName(String productName){ Product product =productMapper.getProductByName(productName); return product;
}
当@Cacheing同时含有CachePut注解和Cacheable注解时,仍然会先执行目标方法。(并不是按@Cacheable的执行过程,先检查缓存,存在则返回)
@CacheConfig
是一个类级别的注解,允许共享缓存的名称、KeyGenerator、CacheManager 和CacheResolver
示例:
@Service
@CacheConfig(cacheNames = "product")
public class ProductService {
}
在类上使用该注解,指定cacheNames属性值,则类中方法上的注解将默认继承了该属性值,如果方法上注解使用和了@CacheConfig向同的属性,则以方法上的为准。
@Service
@CacheConfig(cacheNames = "product")
public class ProductService {
@Autowired
private ProductMapper productMapper; @Cacheable(cacheNames = "product1",key = "#root.methodName+'['+#id+']'")
public Product getProductById(Long id){
Product product =productMapper.getProductById(id);
System.out.println(product);
return product;
}
}
上面@Cacheable和@CacheConfig都指定了属性值cacaeNames,实际以方法上注解指定的为准。
Spring缓存抽象的关键原理就是使用spring AOP,通过切面实现了在方法调用前、调用后获取方法的入参和返回值,进而实现了缓存的逻辑。有一点需要注意的是Spring Aop是通过动态代理机制来实现对目标方法的调用,所以如果该注解方法是在类内部调用而不是在类外部调用,将会导致动态代理时效,从而导致该注解功能时效。
Spring – 缓存注解的更多相关文章
- Spring 缓存注解解析过程
		Spring 缓存注解解析过程 通过 SpringCacheAnnotationParser 的 parseCacheAnnotations 方法解析指定方法或类上的缓存注解, @Cacheable ... 
- Spring缓存注解@Cache使用
		参考资料 http://www.ibm.com/developerworks/cn/opensource/os-cn-spring-cache/ http://swiftlet.net/archive ... 
- Spring缓存注解@Cacheable、@CacheEvict、@CachePut使用(转)
		原文地址:https://www.cnblogs.com/fashflying/p/6908028.html 从3.1开始,Spring引入了对Cache的支持.其使用方法和原理都类似于Spring对 ... 
- Spring 缓存注解之@Cacheable,@CacheEvit
		Spring引入了Cache的支持,其使用方法类似于Spring对事务的支持.Spring Cache是作用于方法上的,其核心思想是,当我们调用一个缓存方法时,把该方法参数和返回结果作为一个键值对存放 ... 
- 【Spring】22、Spring缓存注解@Cache使用
		缓存注解有以下三个: @Cacheable @CacheEvict @CachePut @Cacheable(value=”accountCache”),这个注释的意思是,当调用这个 ... 
- Spring缓存注解@Cacheable、@CacheEvict、@CachePut使用
		从3.1开始,Spring引入了对Cache的支持.其使用方法和原理都类似于Spring对事务管理的支持.Spring Cache是作用在方法上的,其核心思想是这样的:当我们在调用一个缓存方法时会把该 ... 
- Spring缓存注解
		从3.1开始,Spring引入了对Cache的支持.其使用方法和原理都类似于Spring对事务管理的支持.Spring Cache是作用在方法上的,其核心思想是这样的:当我们在调用一个缓存方法时会把该 ... 
- Spring缓存注解@CachePut , @CacheEvict,@CacheConfig使用
		Cacheable CachePut CacheEvict CacheConfig 开启缓存注解 @Cacheable @Cacheable是用来声明方法是可缓存的.将结果存储到缓存中以便后续使用相同 ... 
- 详解Spring缓存注解@Cacheable,@CachePut , @CacheEvict使用
		https://blog.csdn.net/u012240455/article/details/80844361 注释介绍 @Cacheable @Cacheable 的作用 主要针对方法配置,能够 ... 
随机推荐
- 树莓派ubuntu系统下修改config.txt文件 树莓派config.txt文件修改记录
			原文:https://www.raspberrypi.org/documentation/configuration/config-txt.md译文:http://my.oschina.net/fun ... 
- 回文词 (Palindromes,Uva401)
			例题 3-3 回文词 (Palindromes,Uva401) 输入一个字符中,判断它是否为回文串以及镜像串.输入字符串保证不含数字0.所谓回文串,就是反转以后和原串相同,如abba和madam.所有 ... 
- 纪中OJ  2019.02.15【NOIP提高组】模拟 B 组  梦回三国  比赛题解(第一个)
			声明 旁边的同学小 H(胡)对我说: “哟,比赛拿了 140,强!要知道,如果哥第三题 AC 了,哥就 230 了,你个废柴!!!(比赛实际分数 130 额呵)” 顿时,千万草泥马从我心中奔腾而过:你 ... 
- # 2016-2017-2 20155319 《Java程序设计》实验四Android程序开发实验报告
			2016-2017-2 20155319 <Java程序设计>实验四Android程序开发实验报告 实验一 实验内容 Android Stuidio的安装测试: 参考<Java和An ... 
- 20155338 2016-2017-2《Java程序设计》第1周学习总结
			20155338 2016-2017-2<Java程序设计>第1周学习总结 了解成绩构成 成绩构成:100分=翻转课堂考核12次(512 = 60)+ 实验5次(3 5 =15)+ 团队项 ... 
- debug 调试原理理解
			引言: 昨天,看了一篇文章,很受启发,记得之前听别的人远程调试过代码,觉得很神奇,在自己程序里打断点,连接远程服务器,开启调试后可以调用远程方法来看数据的输入和输出,不需要查找问题,重新部署,测试问题 ... 
- .net core 使用windows版redis
			在项目中为了减少程序占用内存(将结果保存在全局变量里面,会占用内存),要求使用redis.开始了爬坑的过程.o(╥﹏╥)o c#操作redis 基本就这3中情况: ServiceStack.Redis ... 
- [IOI2011]Race 点分治
			[IOI2011]Race LG传送门 点分治板子题. 直接点分治统计,统计的时候开个桶维护下就好了. 注(tiao)意(le)细(hen)节(jiu). #include<cstdio> ... 
- ps 图层解锁后变成全格子(全透明)的解决方法
			其实是因为同时打开了好几个ps文件正在编辑中,所以解决方法就是重启ps,然后单独编辑一个文件,解锁后就不会再出现这种情况能,就能正常编辑了 
- 微服务介绍及Asp.net Core实战项目系列之微服务介绍
			0.目录 整体架构目录:ASP.NET Core分布式项目实战-目录 一.微服务选型 在做微服务架构的技术选型的时候,我们以“无侵入”和“社区活跃”为主要的考量点,将来升级为原子服务架构.量子服务架构 ... 
