承接上篇Spingboot Cache
https://blog.csdn.net/weixin_43704975/article/details/97914158
此文采用redis作文缓存中间件
demo
https://github.com/fastmaybe/cache
1 .引入依赖
springboot采用的2.16版本
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
1 .直接贴出主要部分配置文件
pom文件的properties
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<mysql_ip>127.0.0.1</mysql_ip>
<mysql_port>3306</mysql_port>
<mysql_username>root</mysql_username>
<mysql_password>123456</mysql_password>
</properties>
yml
spring:
datasource:
url: jdbc:mysql://@mysql_ip@:@mysql_port@/clouddb01?useUnicode=true&characterEncoding=utf8&useSSL=true&serverTimezone=UTC
username: @mysql_username@
password: @mysql_password@
redis:
host: 127.0.0.1
port: 6379
password: 123456
logging:
level:
com.springboot.cache.mapper: debug #打印sql
3进入正文
背景:解决redis存入的是进制文件,我们需要看到直观的json格式
1使用RedisTemplete,StringRedisTemplete自己编码使用缓存。
先说说RedisTemplete和StringRedisTemplete区别
最主要常见区别是序列化不同
- RedisTemplete默认采用的是JDK序列化方式,StringRedisTemplete采用的是StringRedisSerializer
- RedisTemplete默认注入的范型为Obejct,RedisTemplete<Object, Object>
因此可以自定义额外的RedisTemplete<Object,User>,或者RedisTemplete<Object, Object>覆盖默认的。
自定义RedisTemplete(springboot1.x和2.x没有什么区别(在2.16之前))
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<Object, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
//设置采用Jackson2JsonRedisSerializer序列化方式,可以直观看到json
template.setDefaultSerializer(new Jackson2JsonRedisSerializer<Object>(Object.class));
return template;
}
}
此时如果是自己使用RedisTemplete编码使用缓存,存入的值可以是json展示的。
自定义RedisCacheManager
针对springboot1.x和2.x版本区别比较大
- springboot 1.x
- springboot 1.x默认将RedisTemplate<Object, Object>传入,如果自定义了RedisTemplate<Object, Object>,因此序列化方式直接生肖,也可以自己再定义。
仿照源码写法
- springboot 1.x默认将RedisTemplate<Object, Object>传入,如果自定义了RedisTemplate<Object, Object>,因此序列化方式直接生肖,也可以自己再定义。
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<Object, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
template.setDefaultSerializer(new Jackson2JsonRedisSerializer<Object>(Object.class));
return template;
}
/**
如果参数类型所对应的实例在spring容器中只有一个,则默认选择这个实例。如果有多个,
则需要根据参数名称来选择(参数名称就相当于是spring的配置文件中的bean的id)
*
*/
@Bean
public RedisCacheManager redisCacheManager(RedisTemplate<Object, Object> redisTemplate){
RedisCacheManager redisCacheManager = new RedisCacheManager(redisTemplate);
// 使用前缀,默认会将CacheName作为key的前缀
redisCacheManager.setUsePrefix(true);
return redisCacheManager;
}
}
- springboot 2.x
在2.x版本里面,直接自定义RedisCacheManager就可以实现展示json格式数据,不需要自定义RedisTemplete
@Configuration
public class MyRedisCacheConfig {
/**
* 方式一 建造者 使用GenericJackson2JsonRedisSerializer
* GenericJackson2JsonRedisSerializer序列化后格式:
*
* {
* "@class": "com.springboot.cache.pojo.User",
* "id": 6,
* "name": "瑞文",
* "email": "ruiwen"
* }
*
* @param factory
* @return
*/
// @Bean
public RedisCacheManager cacheManager_one(RedisConnectionFactory factory) {
RedisCacheConfiguration cacheConfiguration =
RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofDays(1))
.disableCachingNullValues()
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new
GenericJackson2JsonRedisSerializer()));
return RedisCacheManager.builder(factory).cacheDefaults(cacheConfiguration).build();
}
/**
* 方式二 构造器 使用Jackson2JsonRedisSerializer
* Jackson2JsonRedisSerializer序列化后格式:
*
* {
* "id": 7,
* "name": "亚索",
* "email": "yasuo"
* }
*
* @param redisConnectionFactory
* @return
*/
@Bean
public RedisCacheManager cacheManager_two(RedisConnectionFactory redisConnectionFactory) {
//初始化一个RedisCacheWriter
RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory);
//设置CacheManager的值序列化方式为json序列化
Jackson2JsonRedisSerializer<Object> objectJackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(Object.class);
RedisSerializationContext.SerializationPair<Object> pair = RedisSerializationContext.SerializationPair
.fromSerializer(objectJackson2JsonRedisSerializer);
RedisCacheConfiguration defaultCacheConfig=RedisCacheConfiguration.defaultCacheConfig()
.serializeValuesWith(pair);
//设置默认超过期时间是30秒
defaultCacheConfig.entryTtl(Duration.ofSeconds(30));
//初始化RedisCacheManager
RedisCacheManager redisCacheManager = new RedisCacheManager(redisCacheWriter, defaultCacheConfig);
return redisCacheManager;
}
}
- GenericJackson2JsonRedisSerializer和Jackson2JsonRedisSerializer的json格式区别
GenericJackson2JsonRedisSerializer:
{
"@class": "com.springboot.cache.pojo.User",
"id": 6,
"name": "瑞文",
"email": "ruiwen"
}
Jackson2JsonRedisSerializer:
{
"id": 6,
"name": "瑞文",
"email": "ruiwen"
}
简单记录此处的源码追踪 基于2.16版本
1 CacheManager
在没有导入缓存中间件的时候,CacheManager为SimpleCacheManager,,并且使用ConcurrentMap来存储数据。
在yml配置文件设置 debug= true在项目启动的时候,可以看到其子类只有SimpleCacheManager。
- 当导入redis后就默认为RedisCacheManager
-图说的是在没有CacheManager类的时候才会使用。
1 RedisCacheManager
- redis自动配置类
- RedisTemplete的序列化为空,就默认采用jdk自带的序列化方式
- StringRedisTemplete的序列化为空,就默认采用StringRedisSerializer序列化方式
翻到一应用篇,可以参考直接应用
https://www.jianshu.com/p/f1a7ef7d0596
可用于锁
Boolean b = (Boolean) redisTemplate.execute(new RedisCallback<Boolean>() {
@Override
public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
RedisSerializer valueSerializer = redisTemplate.getValueSerializer();
RedisSerializer keySerializer = redisTemplate.getKeySerializer();
Object obj = connection.execute("set", keySerializer.serialize("aaaaa"),
valueSerializer.serialize("bbbb"),
SafeEncoder.encode("NX"),
SafeEncoder.encode("EX"),
Protocol.toByteArray(20L));
return obj != null;
}
});
System.out.println(b);