SpringBoot集成Redis,并自定义对象序列化操作

SpringBoot项目使用redis非常简单,pom里面引入redis的场景启动器,在启动类上加@EnableCaching注解,项目启动会自动匹配上redis,这样项目中就可以愉快地使用了,

使用方法:要么使用@Cacheable一类的注解自动缓存,要么使用RedisTemplate手动缓存。

(前提是你的本机或者是远程主机要先搭好redis环境)

虽然SpringBoot好用,但这里也有好多坑,SpringBoot和MySQL一样,易学难精,阳哥说的对,练武不练功,到老一场空。

下面,我将详细记录整合步骤

1.创建一个SpringBoot项目

pom文件中引入cache和redis依赖

<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

2.新建cache数据库,创建员工表employee

写好DAO,service,controller,配置文件application.yml中配好数据源和redis地址

spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3305/cache
    username: root
    password: 123456
  redis:
    host: 127.0.0.1
    port: 6379
    password: hehuiredis177

mybatis:
  configuration:
    map-underscore-to-camel-case: true
  mapper-locations:
  - classpath:mybatis/mapper/*.xml

debug: true

3.SpringBoot主启动类上加@EnableCaching注解

service类@Cacheable(cacheNames=“employee”)注解

@Service
public class EmployeeService {
 @Autowired private EmployeeDao employeeDao;

 @Cacheable(cacheNames="employee")
 public List<Employee> findAll(){
  System.out.println("查询所有员工......");
  return employeeDao.findAll();
 }

 @Cacheable(cacheNames="employee--id")
 public Employee selectEmp(Integer id){
  System.out.println("查询员工:"+id);
  return employeeDao.selectById(id);
 }
}

4.启动项目(application.yml加上debug:true可以将自动配置报告打印在控制台方便观察)

项目启动时,自动配置报告提示Redis已经matched(这里说一下,你如果没有引入redis而又在启动类上加了@EnableCaching注解,SpringBoot会自动给你匹配一个SimpleCacheConfiguration缓存,它的底层用了一个key-value的Map,不能像redis一样持久化,您得注意,好好权衡一下用不用,笔者不建议使用,像SQLite、H2这些一样,玩具型的,只适合个人博客等非正式场合使用,有轻量级的优点,也有不可靠,不好管理的缺点)

5.然后访问 http://localhost:8080/emp/1

500错误,服务端有问题,仔细阅读报错信息,是实体类没有序列化导致的,好吧,那我就实现Serializable接口

6.练武不练功,到老一场空,实现序列化Serializable就可以了吗?

是可以了,但这只是巧合,再去访问,确实可以

去看redis

什么东西啊,看不懂…

但第二次以后确实走了缓存,离成功又近了一步

再去试一下查所有

也可以

缓存也有

7.为什么实现Serializable接口就可以了,这就得开始扒源码了,开始练功…

去看RedisTemplate这个类

对象默认实现序列化

怎么实现的呢?

接着往下看

默认用的是jdk的序列化机制

所以实现Serializable接口就可以,巧合!!!

8.继续练功

redis里这么乱,看不懂,这显然不是我们想要的,我们要的是json,轻量易读的json才是我们的目标,欲存json,必须改变序列化机制,把jdk的序列化替换掉

继续读源码

找到RedisAutoConfiguration这个类,看它是怎么自动配置的

里面有个内部类RedisConfiguration

初始化的时候,把RedisTemplate和StringRedisTemplate放在了IOC容器里,也就是说我们可以在我们自己的代码里注入这两个类,然后手动缓存

而@Cacheable注解使用的是RedisTemplate,那么分析一下RedisTemplate

		@Bean
		@ConditionalOnMissingBean(name = "redisTemplate")
		public RedisTemplate<Object, Object> redisTemplate(
				RedisConnectionFactory redisConnectionFactory)
				throws UnknownHostException {
			RedisTemplate<Object, Object> template = new RedisTemplate<Object, Object>();
			template.setConnectionFactory(redisConnectionFactory);
			return template;
		}
RedisTemplate<Object, Object> template = new RedisTemplate<Object, Object>();

直接new了一个RedisTemplate然后把它返回,呵呵!就从这里入手

@ConditionalOnMissingBean(name = “redisTemplate”)

表示我们可以自定义RedisTemplate,我们有RedisTemplate,就用我们的,否则就用默认,我们不喜欢你的,要json就要自己配一个RedisTemplate

自己写

package com.hehui.config;
import java.net.UnknownHostException;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
/**
 * 自定义redis配置
 * @author hehui
 * @date 2019年3月12日
 *
 */
@Configuration
public class MyRedisConfig {
	@Bean
	public RedisTemplate<Object, Object> redisTemplate(
			RedisConnectionFactory redisConnectionFactory)
			throws UnknownHostException {
		RedisTemplate<Object, Object> template = new RedisTemplate<Object, Object>();
		template.setConnectionFactory(redisConnectionFactory);
		Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<>(Object.class);
		template.setDefaultSerializer(serializer);
		return template;
	}
}
Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer<>(Object.class);
template.setDefaultSerializer(serializer);

只多了这两行代码,其它什么都没变。

为什么要用Jackson2JsonRedisSerializer呢?

因为Jackson2JsonRedisSerializer实现了RedisSerializer接口

9.再访问 http://localhost:8080/emp/1

观察redis

key是我们要的key,value是我们要的value

再刷新页面

不会吧!!!

去缓存找,找到了,反序列化失败…

转换异常,看来不能用Jackson2JsonRedisSerializer,换成GenericJackson2JsonRedisSerializer

换了之后,刷新页面

报错信息变了,这是不能读取json,现在redis里的json是Jackson2JsonRedisSerializer序列化的,

GenericJackson2JsonRedisSerializer当然不认识咯,清了redis再试

好了。

10.试试查所有 http://localhost:8080/list

报错!!!

SimpleKey and no properties discovered 没有key 什么情况?

于是继续读源码,看key是咋生成的

	/**
	 * Generate a key based on the specified parameters.
	 */
	public static Object generateKey(Object... params) {
		if (params.length == 0) {
			return SimpleKey.EMPTY;
		}
		if (params.length == 1) {
			Object param = params[0];
			if (param != null && !param.getClass().isArray()) {
				return param;
			}
		}
		return new SimpleKey(params);
	}

是根据参数来的,我查询所有,是没有参数的,这样key就为空

if (params.length == 0) {
return SimpleKey.EMPTY;
}

这怎么行,开发中,不传参的方法多的很,这样生成key肯定不行撒

于是重写key的生成策略,用【类名+方法名+参数名】这样就可以保证key不为空

package com.hehui.config;
import java.lang.reflect.Method;
import java.net.UnknownHostException;
import java.util.Arrays;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
/**
 * 自定义redis配置
 * @author hehui
 * @date 2019年3月12日
 *
 */
@Configuration
public class MyRedisConfig extends CachingConfigurerSupport{
	@Bean
	public RedisTemplate<Object, Object> redisTemplate(
			RedisConnectionFactory redisConnectionFactory)
			throws UnknownHostException {
		RedisTemplate<Object, Object> template = new RedisTemplate<Object, Object>();
		template.setConnectionFactory(redisConnectionFactory);
//		Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<>(Object.class);
		GenericJackson2JsonRedisSerializer serializer = new GenericJackson2JsonRedisSerializer();
		template.setDefaultSerializer(serializer);
		return template;
	}
	@Bean
	@Override
	public KeyGenerator keyGenerator() {
		return new KeyGenerator() {
            public Object generate(Object target, Method method, Object... objects) {
                StringBuilder sb = new StringBuilder();
                sb.append(target.getClass().getName()).append(".").append(method.getName()).append(Arrays.toString(objects));
                return sb.toString();
            }
        };
	}
}

extends CachingConfigurerSupport并重写keyGenerator方法

测试通过

redis

json中还带有@Class相当好。

11.好啦,相当曲折地把redis整合并自定义配置到SpringBoot中。

源码github地址:https://github.com/hehuihh/springboot_redis

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • SpringBoot Redis配置Fastjson进行序列化和反序列化实现

    FastJson是阿里开源的一个高性能的JSON框架,FastJson数据处理速度快,无论序列化(把JavaBean对象转化成Json格式的字符串)和反序列化(把JSON格式的字符串转化为Java Bean对象),都是当之无愧的fast:功能强大(支持普通JDK类,包括javaBean, Collection, Date 或者enum):零依赖(没有依赖其他的任何类库). 1.写一个自定义序列化类 /** * 自定义序列化类 * @param <T> */ public class FastJ

  • 如何自定义redis工具jar包供其他SpringBoot项目直接使用

    注:(最终redis数据库连接信息由使用者项目模块配置提供) 一.Redis常用存储操作实现(redis-util模块,该module最后会打包成jar供其他服务使用) 1.引用相关依赖 <!-- 如果有继承父级spring-boot-starter-parent,可不用添加版本号 --> <!-- Redis缓存 [start] --> <dependency> <groupId>org.springframework.boot</groupId&g

  • SpringBoot2.3整合redis缓存自定义序列化的实现

    1.引言 我们使用redis作为缓存中间件时,当我们第一次查询数据的时候,是去数据库查询,然后查到的数据封装到实体类中,实体类会被序列化存入缓存中,当第二次查数据时,会直接去缓存中查找被序列化的数据,然后反序列化被我们获取.我们在缓存中看到的序列化数据不直观,如果想看到类似json的数据格式,就需要自定义序列化规则. 2.整合redis pom.xml: <!--引入redis--> <dependency> <groupId>org.springframework.d

  • springboot自定义redis-starter的实现

    spring时代整合redis spring我相信只要是一个Java开发人员我相信再熟悉不过了,几乎垄断了整个JavaEE的市场份额,话不多说进入正题. 首先看看我们在spring中整合redis需要做什么 1.首先maven工程的话不用想先导入依赖 <!-- jedis --> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> &

  • SpringBoot集成Redis,并自定义对象序列化操作

    SpringBoot项目使用redis非常简单,pom里面引入redis的场景启动器,在启动类上加@EnableCaching注解,项目启动会自动匹配上redis,这样项目中就可以愉快地使用了, 使用方法:要么使用@Cacheable一类的注解自动缓存,要么使用RedisTemplate手动缓存. (前提是你的本机或者是远程主机要先搭好redis环境) 虽然SpringBoot好用,但这里也有好多坑,SpringBoot和MySQL一样,易学难精,阳哥说的对,练武不练功,到老一场空. 下面,我将

  • springBoot集成redis的key,value序列化的相关问题

    使用的是maven工程 springBoot集成redis默认使用的是注解,在官方文档中只需要2步; 1.在pom文件中引入即可 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-redis</artifactId> </dependency> 2.编写一个CacheService接口,使用redisCach

  • springboot集成redis存对象乱码的问题及解决

    目录 springboot集成redis存对象乱码 话不多说上代码 可以考虑使用StringRedisTemplete 解决redis乱码问题 直接添加一个配置类就行了 springboot集成redis存对象乱码 其实本质上不算是一种乱码,只是序列化之后存储的东西而已,当我们使用RedisTemplete存储对象,时,如果该对象没有被序列化则会报错,序列化之后得到的不是自己想要的数据,为了解决这种方法,我们可以使用 StringRedisTemplete 话不多说上代码 默认使用rediste

  • SpringBoot集成Redis的思路详解

    目录 SpringBoot集成Redis 1.概述 2.测试Redis 3.自定义redisTemplate SpringBoot集成Redis 1.概述 Redis是什么? Redis(Remote Dictionary Server ),即远程字典服务. 是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并提供多种语言的API. 与memcached一样,为了保证效率,数据都是缓存在内存中.区别的是redis会周期性的把更新的数据写入磁盘

  • Java SpringBoot 集成 Redis详解

    目录 1.概述 Redis是什么? Redis能该干什么? 特性 2.测试Redis 3.自定义redisTemplate 1.概述 Redis是什么? Redis(Remote Dictionary Server ),即远程字典服务. 是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并提供多种语言的API. 与memcached一样,为了保证效率,数据都是缓存在内存中.区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加

  • 使用SpringBoot集成redis的方法

    今天,日月在这里教大家如何使用springBoot集成redis,说实话比较简单,网上也有大把的教程.先套用一下网上的简介. 定义 REmote DIctionary Server(Redis) 是一个由Salvatore Sanfilippo写的key-value存储系统. Redis是一个开源的使用ANSI C语言编写.遵守BSD协议.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并提供多种语言的API. 它通常被称为数据结构服务器,因为值(value)可以是 字符串(S

  • SpringBoot 集成Redis 过程

    Redis 介绍: Redis 服务 Redis (REmote Dictionary Server) 是一个由Salvatore Sanfilippo 完成的key-value存储系统,是跨平台的非关系型数据库. Redis 是一个开源的使用ANSI C语言编写.遵循BSD 协议的.支持网络.可基于内存.分布式.可选择持久性的键值对存储数据库,并提供多语言的API. Redis 通常被认为是数据结构服务器,其值可以是字符串.哈希.列表.集合以及有序集合. Redis 优点 异常快,每秒可以执行

  • springboot集成redis lettuce

    目前java操作redis的客户端有jedis跟Lettuce.在springboot1.x系列中,其中使用的是jedis,但是到了springboot2.x其中使用的是Lettuce. 因为我们的版本是springboot2.x系列,所以今天使用的是Lettuce. 关于jedis跟lettuce的区别: Lettuce 和 Jedis 的定位都是Redis的client,所以他们当然可以直接连接redis server. Jedis在实现上是直接连接的redis server,如果在多线程环

  • SpringBoot集成Redis并实现主从架构的实践

    目录 一.Windows环境下安装Redis 设置键值对 根据key获取value 二.SpringBoot连接Redis (1)使用Jedis类直接连接Redis服务器 (2)通过配置文件进行连接 三.使用连接池操作Redis 今天这篇文章来和大家分享一下在springboot中如何集成redis,并实现主从架构,进行数据的简单存储. 我的Redis是部署在Windows系统下面的,所以在这里附上Redis在Windows环境下的安装地址和安装说明. 一.Windows环境下安装Redis 首

  • SpringBoot集成Redis数据库,实现缓存管理

    目录 一.Redis简介 二.Spring2.0集成Redis 1.核心依赖 2.配置文件 3.简单测试案例 4.自定义序列化配置 5.序列化测试 三.源代码地址 一.Redis简介 Spring Boot中除了对常用的关系型数据库提供了优秀的自动化支持之外,对于很多NoSQL数据库一样提供了自动化配置的支持,包括:Redis, MongoDB, Elasticsearch.这些案例整理好后,陆续都会上传Git. SpringBoot2 版本,支持的组件越来越丰富,对Redis的支持不仅仅是扩展

随机推荐