前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring Cache-缓存注解(二)

Spring Cache-缓存注解(二)

作者头像
小小工匠
发布2021-08-17 15:31:42
3580
发布2021-08-17 15:31:42
举报
文章被收录于专栏:小工匠聊架构小工匠聊架构

文章目录

导读

Spring-Cache手札

Spring Cache抽象-缓存注解

实战-Redis-20Spring缓存机制整合Redis

关于Spring Cache以及注解,之前总结了几篇。现在我们再来细化下


概述

注解

描述

@Cacheable

表明在进入方法之前, Spring 会先去缓存服务器中查找对应 key 的缓存值,如果找到缓存值,那么 Spring 将不会再调用方法,而是将缓存值读出,返回给调用者;如果没有找到缓存值,那么 Spring 就会执行你的方法,将最后的结果通过 key 保存到缓存服务器中

@CachePut

Spring 会将该方法返回的值缓存到缓存服务器中,这里简要注意的是, Spring 不会事先去缓存服务器中查找,而是直接执行方法,然后缓存。换句话说,该方法始终会被 Spring 所调用

@CacheEvict

移除缓存对应的 key 的值

@Caching

这是一个分组注解,它能够同时应用于其他缓存的注解

  • 注解@Cacheable 和@CachePut 都可以保存缓存键值对,只是它们的方式略有不同, 请注意二者的区别,它们只能运用于有返回值的方法中
  • 而删除缓存 key 的@CacheEvict 则可以用在 void 的方法上,因为它并不需要去保存任何值 。
  • 上述注解都能标注到类或者方法之上,如果放到类上,则对所有的方法都有效,如果放到方法上,则只是对方法有效。
  • 在大部分情况下,会放置到方法上。 @Cacheable 和 @CachePut 可以配置的属性接近。
  • 一般而言,对于查询,我们会考虑使用@Cacheable
  • 对于插入和修改,考虑使用@CachePut
  • 对于删除操作,我们会考虑使用@CacheEvict。

注解@Cacheable 和@CachePut

因为@Cacheable 和@CachePut 两个注解的配置项 比较接近,所以这里就将这两个注解一并来看

属性

配置类型

说明

value

String[]

使用缓存的名称

condition

String

Spring 表达式,如果表达式返回值为 false,则不会将缓存应用到方法上, true 则会

key

String

Spring 表达式,可以通过它来计算对应缓存的 key

unless

String

Spring 表达式,如果表达式返回值为 true,则不会将方法的结果放到缓存上

value 和 key 这两个属性使用得最多,所以先来讨论这两个属性。

value 是一个数组,可以引用多个缓存管理器.

案例----->https://blog.csdn.net/yangshangwei/article/details/82961772#Service_664

如上代码所示定义redisCacheManager后就可以引用它了,而对于 key 则是缓存中的键,它支持 Spring 表达式,通过 Spring 表达式就可以自定义缓存的 key。


表达式值的引用

Spring 表达式和缓存注解之间的约定,通过这些约定去引用方法的参数和返回值的内容,使得其注入 key 所定义的 Spring 表达式的结果中。

表达式

描述

备注

#root.args

定义传递给缓存方法的参数

不常用,暂不讨论

#root.caches

该方法执行是对应的缓存名称,它是一个数组

不常用,暂不讨论

#root.target

执行缓存的目标对象

不常用,暂不讨论

#root.targetClass

目标对象的类,它是#root.target.class 的缩写

不常用,暂不讨论

#root.method

缓存方法

不常用,暂不讨论

#root.methodName

缓存方法的名称,它是#root.method.name 的缩写

不常用,暂不讨论

#result

方法返回结果值,还可以使用 Spring 表达式进一步读取其属性

请注意该表达式不能用于注解@Cacheable,因为该注解的方法可能不会被执行,这样返回值就无从谈起了

#Argument

任意方法的参数,可以通过方法本身的名称或者下标去定义

比如 getRole(Long id)方法,想读取 id 这个参数,可以写为#id,或者#a0、#p0,建议写为#id,可读性高

这样就方便使用对应的参数或者返回值作为缓存的 key 了。


注解@CacheEvict

注解@CacheEvict 主要是为了移除缓存对应的键值对,主要对于那些删除的操作,先来了解它存在哪些属性。

属性

配置类型

说明

value

String[]

要使用缓存的名称

key

String

Spring 表达式,可以通过它来计算对应缓存的 key

condition

String

Spring 表达式,如果表达式返回值为 false,则不会将缓存应用到方法上, true 则会

allEntries

boolean

如果为 true,则删除特定缓存所有键值对,默认值为 false,请注意它将消除所有缓存服务器的缓存,这个属性慎用

beforelnvocation

boolean

指定在方法前后移除缓存,如果指定为 true,则在方法前删除缓存:如果为 false,则在方法调用后删除级存,默认值为 false

  • value 和 key 与之前的@Cacheable 和@CachePut 是一致的。
  • 属性 allEntries 要求删除缓存服务器中所有的缓存,这个时候指定的 key 将不会生效,所以这个属性要慎用
  • beforeInvocation 属性指定缓存在方法前或者方法后移除。

案例

Spring缓存机制整合Redis

代码语言:javascript
复制
package com.artisan.ssm_redis.service.impl;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.artisan.ssm_redis.dao.RoleDao;
import com.artisan.ssm_redis.domain.Role;
import com.artisan.ssm_redis.service.RoleService;


@Service
public class RoleServiceImpl implements RoleService {

	// 自动注入
	@Autowired
	private RoleDao roleDao;

	/**
	 * 使用@Cacheable定义缓存策略 当缓存中有值,则返回缓存数据,否则访问方法得到数据 通过value引用缓存管理器,通过key定义键
	 * 
	 * @param id
	 *            角色编号
	 * @return 角色
	 */
	@Override
	@Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRED)
	@Cacheable(value = "redisCacheManager", key = "'redis_role_'+#id")
	public Role getRole(Long id) {
		return roleDao.getRole(id);
	}

	/**
	 * 使用@CachePut则表示无论如何都会执行方法,最后将方法的返回值再保存到缓存中
	 * 使用在插入数据的地方,则表示保存到数据库后,会同期插入到Redis缓存中
	 * 
	 * @param role
	 *            角色对象
	 * @return 角色对象(会回填主键)
	 */
	@Override
	@Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRED)
	@CachePut(value = "redisCacheManager", key = "'redis_role_'+#result.id")
	public Role insertRole(Role role) {
		roleDao.insertRole(role);
		return role;
	}

	/**
	 * 使用@CachePut,表示更新数据库数据的同时,也会同步更新缓存
	 * 
	 * @param role
	 *            角色对象
	 * @return 影响条数
	 */
	@Override
	@Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRED)
	@CachePut(value = "redisCacheManager", key = "'redis_role_'+#role.id")
	public int updateRole(Role role) {
		return roleDao.updateRole(role);
	}

	/**
	 * 使用@CacheEvict删除缓存对应的key
	 * 
	 * @param id
	 *            角色编号
	 * @return 返回删除记录数
	 */
	@Override
	@Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRED)
	@CacheEvict(value = "redisCacheManager", key = "'redis_role_'+#id")
	public int deleteRole(Long id) {
		return roleDao.deleteRole(id);
	}

}
本文参与?腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018-10-08 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客?前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与?腾讯云自媒体同步曝光计划? ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 文章目录
  • 导读
  • 概述
  • 注解@Cacheable 和@CachePut
    • 表达式值的引用
    • 注解@CacheEvict
    • 案例
    相关产品与服务
    云数据库 Redis
    腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
    http://www.vxiaotou.com