SpringCache
Spring Cache
通过注解来实现缓存,底层可以切换不同的cache实现,通过CacheManager接口来统一不同的缓存技术
对不同的缓存技术需要实现不同的CacheManager
CacheManager | 描述 |
---|---|
EhCacheCacheManager | 使用EhCache缓存技术 |
GuavaCacheManager | 使用Guava缓存技术 |
RedisCacheManager | 使用Redis缓存技术 |
常用注解
注解 | 说明 |
---|---|
@EnableCaching | 开启缓存注解功能 |
@Cacheable | 优先从缓存中取数据,没有去数据库取 |
@CachePut | 将方法返回值放到内存中 |
@CacheEvict | 将一条或多条数据从缓存中删除 |
实例1
导入坐标
1 |
|
配置相应技术
1 |
|
启动类加@EnableCaching注解
在要缓存的方法上加注解, 返回值会被存到redis中, 返回值必须是可序列化的
1 |
|
实例2
在微服务中使用spring cache
例子来自尚医通
在common组件中添加依赖
1
2
3
4
5
6
7
8
9
10
11
12<!-- redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- spring2.X集成redis所需common-pool2-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>2.7.0</version>
</dependency>在common组件中添加redis配置类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85package com.xw.config;
@Configuration
@EnableCaching
public class RedisConfig {
/**
* 自定义key规则
* @return
*/
@Bean
public KeyGenerator keyGenerator() {
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();
}
};
}
/**
* 设置RedisTemplate规则
* @param redisConnectionFactory
* @return
*/
@Bean
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
//解决查询缓存转换异常的问题
ObjectMapper om = new ObjectMapper();
// 指定要序列化的域,field,get和set,以及修饰符范围,ANY是都有包括private和public
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
// 指定序列化输入的类型,类必须是非final修饰的,final修饰的类,比如String,Integer等会跑出异常
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
//序列号key value
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
/**
* 设置CacheManager缓存规则
* @param factory
* @return
*/
@Bean
public CacheManager cacheManager(RedisConnectionFactory factory) {
RedisSerializer<String> redisSerializer = new StringRedisSerializer();
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
//解决查询缓存转换异常的问题
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
// 配置序列化(解决乱码的问题),过期时间600秒
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofSeconds(600))
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
.disableCachingNullValues();
RedisCacheManager cacheManager = RedisCacheManager.builder(factory)
.cacheDefaults(config)
.build();
return cacheManager;
}
}在使用到缓存的模块中添加配置
1
2
3
4
5
6
7
8
9
10spring.redis.host=127.0.0.1
spring.redis.port=6379
spring.redis.database= 0
spring.redis.timeout=1800000
spring.redis.lettuce.pool.max-active=20
spring.redis.lettuce.pool.max-wait=-1
#最大阻塞等待时间(负数表示没限制)
spring.redis.lettuce.pool.max-idle=5
spring.redis.lettuce.pool.min-idle=0在需要缓存的方法上添加注解
1
2
3
4
5
6
7
8
9
10
11
12
13// 根据id查询子数据列表
@Cacheable(value = "dict",keyGenerator = "keyGenerator")
@Override
public List<Dict> findChildData(Long id) {
LambdaQueryWrapper<Dict> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Dict::getParentId, id);
List<Dict> dictList = baseMapper.selectList(wrapper);
for (Dict dict : dictList) {
boolean hasChildren = this.isChildren(dict.getId());
dict.setHasChildren(hasChildren);
}
return dictList;
}
SpringCache
http://xwww12.github.io/2022/08/19/spring/SpringCache/