赞
踩
Spring Cache默认使用的是ConcurrentMapCacheManager管理器
创建的是ConcurrentMapCache缓存 然后将数据保存在ConcurrentMap中
实际使用缓存中间件的场合会更多 例如Redis EhCache等
Spring Cache默认使用的是SimpleCacheConfiguration这个配置类
当然 还有其他很多配置类(默认是不开启的
当导入其他相应的缓存场景即可自动开启对应的缓存配置
首先 如果机器上还没装Redis 可使用Docker安装Redis
# 拉取最新redis镜像
docker pull docker.mirrors.ustc.edu.cn/library/redis
#启动redis容器
docker run -d -p 6379:6379 --name redis1 docker.mirrors.ustc.edu.cn/library/redis
当然自己安装Redis然后配置也可
然后 在项目中引入redis的starter(启动器):
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
然后在配置文件中配置Redis的主机ip:
spring.redis.host=111.111.111.111(主机ip)
当引入了Redis的starter(启动器)之后 RedisAutoConfiguration这个配置类就启动了
底层配置了RedisTemplate和StringRedisTemplate 这两个Template类是用于操作Redis的 就类似于JDBC的JdbcTemplate
若要使用 只需注入即可
StringRedisTemplate 顾名思义 是操作字符串的
而RedisTemplate是用来操作对象的
Redis常用五大数据类型:String字符串 List列表 Set集合 Hash散列 ZSet有序集合
Template都有对应的方法
stringRedisTemplate.opsForValue()
:操作k-v字符串
stringRedisTemplate.opsForList()
:操作列表
stringRedisTemplate.opsForSet()
:操作集合
stringRedisTemplate.opsForHash()
:操作散列
stringRedisTemplate.opsForZSet()
:操作有序集合
redisTemplate里也有这些方法
// 添加key-value
stringRedisTemplate.opsForValue().append("msg","HelloWorld");
// 通过key获取指定的value
System.out.println(stringRedisTemplate.opsForValue().get("msg"));
// 往list左侧添加
stringRedisTemplate.opsForList().leftPush("mylist","1");
stringRedisTemplate.opsForList().leftPush("mylist","2");
stringRedisTemplate.opsForList().leftPush("mylist","3");
具体语法和Redis的是一样的 不过多阐述
Employee employee = employeeMapper.findEmployeeById(1);
redisTemplate.opsForValue().set("emp1",employee);
此时 会报错:Caused by: java.lang.IllegalArgumentException: DefaultSerializer requires a Serializable payload but received an object of type [net.zjitc.springboot.bean.Employee]
因为 需要传入可序列化的类 而存入的类不可被序列化 因此报错
需要在实体类上实现Serializable接口 Serializable只是一个声明 代表该类是可以被序列化的 仅此而已
public class Employee implements Serializable {
private Integer id;
private String lastName;
private String email;
private Integer gender;
private Integer dId;
...
}
这样即可将对象正常 存入Redis了
默认保存对象使用的是JDK序列化机制 将序列化后的数据保存到Redis中
因而保存后的数据会多了很多诸如\xAC\xED\x00\x05sr\x00
这样的乱码
平时的使用的话 通常是将数据以JSON的形式保存
有两种方法可以实现转换:
在RedisTemplate中 定义了很多序列化器 默认使用的是JdkSerializationRedisSerializer
只需要改变其为JSON的序列化器 即可
自定义一个Redis的配置类:
@Configuration public class MyRedisConfig { @Bean public RedisTemplate<Object, Employee> empRedisTemplate( RedisConnectionFactory redisConnectionFactory) throws UnknownHostException { RedisTemplate<Object, Employee> template = new RedisTemplate<>(); template.setConnectionFactory(redisConnectionFactory); // 传入要转换为JSON的类的class Jackson2JsonRedisSerializer<Employee> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Employee>(Employee.class); template.setDefaultSerializer(jackson2JsonRedisSerializer); return template; } }
配置好之后 在类里注入即可使用:
// 注入
@Autowired
RedisTemplate<Object, Employee> empRedisTemplate;
// 使用
Employee employee = employeeMapper.findEmployeeById(1);
empRedisTemplate.opsForValue().set("emp1",employee);
完美
其实原理就是CacheManager缓存管理器创建出Cache缓存组件
然后由Cache缓存组件来进行实际的CRUD操作
引入Redis的starter启动器之后 经过内部的判断 容器中就会自动使用RedisCacheManager(Redis缓存管理器)
RedisCacheManager创建了RedisCache作为缓存组件 该缓存组件是通过操作Redis来缓存数据
而这一切 都是自动配置好的
Just enjoy it
在使用SpringCache缓存抽象的注解来实现缓存时 若引入了Redis的starter(启动器)
则@Cacheable缓存数据会自动储存到Redis中
然鹅 默认还是用的是JDK序列化 储存到Redis中的还是一堆乱码!
那么 如何储存为JSON数据?
在引入了Redis的starter之后 默认使用的CacheManager是RedisCacheManager
默认创建的RedisCacheManager操作Redis的时候使用的是RedisTemplate<Object,Object>
请注意 泛型是Object,Object
而这个默认的RedisTemplate<Object,Object>
使用的序列化机制正是JdkSerializationRedisSerializer 它会导致存储(中文)乱码
此时 需要自定义CacheManager
在配置类中往容器里添加一个CacheManager:
// 定制缓存管理器规则 @Bean public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) { //初始化RedisCacheWriter RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory); //设置CacheManager的序列化方式为JSON RedisSerializer<Object> jsonSerializer = new GenericJackson2JsonRedisSerializer(); RedisSerializationContext.SerializationPair<Object> pair = RedisSerializationContext.SerializationPair .fromSerializer(jsonSerializer); RedisCacheConfiguration defaultCacheConfig=RedisCacheConfiguration.defaultCacheConfig() .serializeValuesWith(pair); //设置默认超时过期时间 // defaultCacheConfig.entryTtl(Duration.ofSeconds(30)); return new RedisCacheManager(redisCacheWriter, defaultCacheConfig); }
默认的CacheManager生效条件是当容器中没有CacheManager 因此 自己编写的CacheManager一旦添加到容器中 自动会生效
默认会使用前缀 即 默认将注解的cacheNames属性的值作为key的前缀 避免了key重复
不仅可用注解方式 还可单独使用编码方式来操作缓存管理器:
首先要注入缓存管理器 然后直接使用即可(当然 前提是已经自定义了CacheManager 如果你想以JSON格式储存到Redis的话)
// 缓存管理器 @Autowired CacheManager cacheManager; public Department getDepartmentById(Integer id) { System.out.println("查询"+id+"部门"); Department employee = departmentMapper.findEmployeeById(id); // 获取一个指定名称的缓存 Cache dept = cacheManager.getCache("dept"); // 对指定缓存进行操作 会自动添加前缀 dept.put(id,employee); return employee; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。