SpringBoot 2X 整合redis json序列化
环境搭建
pringboot 2x+redis 2.8.9
导入依赖(pom.xml)
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.lmh</groupId>
<artifactId>spring-boot-07</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-boot-07</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.3</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
其中mybatis的starter和mysql依赖为了测试
导入redis的starter后
- 启动Redis
- 启动redis可视化工具 Redis Desktop Manager (可以去下载,熟悉命令可以不用,可视化工具方便操作)连接redis
- 配置全局配置文件application.properties或application.yaml
spring:
datasource:
username: root
password: xxxxx
url: jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false
driver-class-name: com.mysql.cj.jdbc.Driver
redis:
host: 127.0.0.1
上配置mysql数据源,redis host 的值取决于你连接的Redis服务器ip地址,可自定义修改
4.根据需要自定义redisConfig配置类
自定义配置类修改序列化
阅读RedisAutoConfiguration源码
/*
* Copyright 2012-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.autoconfigure.data.redis;
import java.net.UnknownHostException;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
/**
* {@link EnableAutoConfiguration Auto-configuration} for Spring Data's Redis support.
*
* @author Dave Syer
* @author Andy Wilkinson
* @author Christian Dupuis
* @author Christoph Strobl
* @author Phillip Webb
* @author Eddú Meléndez
* @author Stephane Nicoll
* @author Marco Aust
* @author Mark Paluch
* @since 1.0.0
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(RedisOperations.class)
@EnableConfigurationProperties(RedisProperties.class)
@Import({ LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class })
public class RedisAutoConfiguration {
@Bean
@ConditionalOnMissingBean(name = "redisTemplate")
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory)
throws UnknownHostException {
RedisTemplate<Object, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
//redisConnectionFactory里默认的序列化为jdk
return template;
}
@Bean
@ConditionalOnMissingBean
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory)
throws UnknownHostException {
StringRedisTemplate template = new StringRedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
}
提供了RedisTemplate操作数据,redisConnectionFactory提供set方法可以修改序列化机制,springboot starter导入了json则可配置
json序列化配置类
@Configuration
public class RedisConfig {
/**
* 可根据自己的需要改其泛型,和序列化器,使数据可以json形式序列化保存到javabean,javabean中要继承接口Serializable
*
* @param redisConnectionFactory
* @return
* @throws UnknownHostException
*/
@Bean
public RedisTemplate<Object, Object> myRedisTemplate(RedisConnectionFactory redisConnectionFactory)
throws UnknownHostException {
RedisTemplate<Object, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
Jackson2JsonRedisSerializer<Object> objectJackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(Object.class);
template.setDefaultSerializer(objectJackson2JsonRedisSerializer);//修改默认setDefaultSerializer序列化工具
return template;
}
/**
* 将数据写入redis中转为json,解决序列化问题的配置
* 作用有可以在可视化redis中以json数据格式存储,解决了序列化乱码的问题
*可以自定义序列化,将其fromSerializer(jackson2JsonRedisSerializer)改成想要的序列化类
* @param redisConnectionFactory
* @return
*/
@Bean
RedisCacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
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);
//配置序列化(解决乱码的问题)
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ZERO)
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
.disableCachingNullValues();
RedisCacheManager cacheManager = RedisCacheManager.builder(redisConnectionFactory)
.cacheDefaults(config)
.build();
return cacheManager;
}
}
原理:CacheManager==Cache 缓存组件来实际缓存中存取数据
-
1.引入redis的starter,容器中保存的是RedisCacheManager
-
2.RedisCacheManager创建RedisCache来作为缓存组件,RedisCache操作redis数据库
-
3.默认保存数据k-v都是Object,利用序列化保存;如何保存json
-
引入redis的Starter,CacheManager变为RedisCacheManager
-
默认创建的RedisCacheManager操作redis时利用的是RedisTemplate<Object,Object>默认为jdk序列化机制
-
自己配置RedisCacheManager,让系统使用自己写的,关键配置见上面配置类`
整合测试
@SpringBootTest
class SpringBoot07ApplicationTests {
@Autowired
private StudentMapper studentMapper;//自定义操作数据库得Mapper参与测试
@Autowired
private RedisTemplate redisTemplate;//操作k-v是对象的
@Autowired
private StringRedisTemplate stringRedisTemplate;//操作k-v是字符串的
@Autowired
private RedisTemplate<Object, Object> myRedisTemplate;
/**
* Redis常见的五大数据类型
* String,List,Set(集合),Hash(散列表),ZSet(有序集合)
* 操作示例:
* stringRedisTemplate.opsForValue().append("msg","hello");
* redisTemplate.opsForValue().append("msg","hello");
* 其中后面命令都是redis的命令
* opsForValue()(操作字符串)
* opsForSet()(操作集合)
* 。。。。等等
* 保存对象时
* redisTemplate.opsForValue().set("key值","对象名");
* 其中序列化,可以自己改,默认为JdkSerializationRedisSerializer,有需要可以改,改配置件config包类
*
* @throws Exception
*/
@Test
void testRedis() throws Exception {
stringRedisTemplate.opsForValue().append("msg", "hello");
stringRedisTemplate.opsForValue().append("msg", "world");
System.out.println(stringRedisTemplate.opsForValue().get("msg"));
}
/**
* 测试保存对象
* @throws Exception
*/
@Test
void testRedis1()throws Exception{
Student student = studentMapper.findById(1);
myRedisTemplate.opsForValue().set("student",student);
}//测试代码块和注释
缓存使用
当导入redis starter 系统将会使用redis作为缓存工具
相关缓存使用文章见 springboot缓存使用