SpringBoot2.3.0自定义RedisCacheManager并对缓存Jackson序列化

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringBoot2.3.0自定义RedisCacheManager并对缓存Jackson序列化相关的知识,希望对你有一定的参考价值。

版本:

spring-boot:2.3.0
redis:latest(Docker)

依赖

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

application.yml

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: root
    password: root
    url: jdbc:mysql://localhost:3306/spring_boot?serverTimezone=GMT%2B8
    type: com.mysql.cj.jdbc.MysqlDataSource

  jpa:
    show-sql: true
    database: mysql
    hibernate:
      ddl-auto: update

  redis:
    host: 127.0.0.1
  cache:
    redis:
      use-key-prefix: true

在spring-boot2.x之前

RedisCacheManager cacheManager = new RedisCacheManager(RedisTemplate redisTemplate);

spring-boot2.0后

RedisCacheManager cacheManager = new RedisCacheManager(RedisCacheWriter redisCacheWriter,RedisCacheConfiguration redisCacheConfiguration);

步骤:

开始:

写一个配置类

给容器注册一个Bean,返回缓存管理器
这里redisTemplate容器中有,所以会自动注入

@Configuration
public class CustomizeRedisCacheManager {

    @Bean
    public CacheManager customizeCacheManager(RedisTemplate redisTemplate) {

    }

}

@Configuration
public class CustomizeRedisCacheManager {

@Bean
public CacheManager customizeCacheManager(RedisTemplate redisTemplate) {

}

}

RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(Objects.requireNonNull(redisTemplate.getConnectionFactory()));

第二步:

创建Jackson对象并传入需要序列化的对象

Jackson2JsonRedisSerializer<RedisUser> serializer = new Jackson2JsonRedisSerializer<>(RedisUser.class);

第三步:

传入 Jackson对象 并获取 RedisSerializationContext对象

RedisSerializationContext<RedisUser, RedisUser> serializationContext = RedisSerializationContext.fromSerializer(serializer);

第四步:

配置RedisCacheConfiguration

RedisCacheConfiguration.defaultCacheConfig()
serializeValuesWit(SerializationPari<?> valueSerializationPari)
设置 value 的序列化
serializeKeysWith(SerializationPari valueSerializationPari)
设置 key 的序列化

RedisCacheConfiguration redisCacheConfiguration =  RedisCacheConfiguration.defaultCacheConfig().serializeValuesWith(serializationContext.getValueSerializationPair());

经测试:如果用如下配置无效

RedisSerializationContext.SerializationPair<RedisUser> redisUserSerializationPair = RedisSerializationContext.SerializationPair.fromSerializer(serializer);

最后一步:

创建RedisCacheManager(RedisCacheWriter redisCacheWriter, RedisCacheConfiguration redisCacheConfiguration)对象并返回

return new RedisCacheManager(redisCacheWriter,redisCacheConfiguration);

完整示例

package com.live.config;

import com.live.model.RedisUser;
import org.springframework.cache.CacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;

import java.util.Objects;

@Configuration
public class CustomizeRedisCacheManager {

    @Bean
    public CacheManager customizeCacheManager(RedisTemplate redisTemplate) {
        RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(Objects.requireNonNull(redisTemplate.getConnectionFactory()));

        Jackson2JsonRedisSerializer<RedisUser> serializer = new Jackson2JsonRedisSerializer<>(RedisUser.class);

        RedisSerializationContext<RedisUser, RedisUser> serializationContext = RedisSerializationContext.fromSerializer(serializer);
        RedisCacheConfiguration redisCacheConfiguration =  RedisCacheConfiguration.defaultCacheConfig().serializeValuesWith(serializationContext.getValueSerializationPair());

        return new RedisCacheManager(redisCacheWriter,redisCacheConfiguration);
    }

}

一步写完是这个样子的

@Bean(name = "myCacheManager")
public CacheManager customizerRedisCacheManager(RedisTemplate redisTemplate) {
    return new RedisCacheManager(
            RedisCacheWriter
                    .nonLockingRedisCacheWriter(Objects
                            .requireNonNull(redisTemplate
                                    .getConnectionFactory())),
            RedisCacheConfiguration
                    .defaultCacheConfig()
                    .serializeValuesWith(
                            RedisSerializationContext
                                    .fromSerializer(new Jackson2JsonRedisSerializer<>(RedisUser.class))
                                    .getValueSerializationPair()));
}

对结果缓存
@Cacheable(cacheNames = “redisUser”, key = “#id”, cacheManager = “customizeCacheManager”)
cacheManager指定我们自定义的RedisCacheManager
这里注意: 如果使用的JPA,不要使用findById(id).get() 来返回对象;会反序列化失败

@Service
public class RedisUserService {

    @Autowired
    JPARepository jpaRepository;

    @Cacheable(cacheNames = "redisUser", key = "#id", cacheManager = "customizeCacheManager")
    public Optional<RedisUser> findOneById(Integer id) {
        return jpaRepository.findById(id);
    }

}

效果:成功对缓存json序列化

技术图片
其它代码(Model、Repository、Service、Controller)
Model

package com.live.model;

import lombok.Data;

import javax.persistence.*;
import java.io.Serializable;

@Data
@Entity
@Table(name = "redis_user")
public class RedisUser implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    @Column(name = "redis_name",length = 100,unique = true)
    private String name;
    @Column(name = "redis_password", length = 125, nullable = false)
    private String password;

}

Repository

import com.live.model.RedisUser;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface JPARepository extends JpaRepository<RedisUser,Integer> {}

Service

@Service
public class RedisUserService {

    @Autowired
    JPARepository jpaRepository;

    @Cacheable(cacheNames = "redisUser", key = "#id", cacheManager = "customizeCacheManager")
    public Optional<RedisUser> findOneById(Integer id) {
        return jpaRepository.findById(id);
    }

}

Controller

package com.live.controller;

import com.live.model.RedisUser;
import com.live.service.RedisUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import java.util.Optional;

@RestController
public class RedisController {

    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    RedisUserService redisUserService;

    @GetMapping("/redis/findOne/{id}")
    public Optional<RedisUser> findOneById(@PathVariable(value = "id") Integer id) {
        return redisUserService.findOneById(id);
    }

}

以上是关于SpringBoot2.3.0自定义RedisCacheManager并对缓存Jackson序列化的主要内容,如果未能解决你的问题,请参考以下文章

spring-boot-mybatis-plus-layui 自定义代码生成完整多对一

spring-boot-mybatis-plus-layui 自定义代码生成完整多对一

Spring Boot 2.3.0 - MongoDB 库不会自动创建索引

Spring Boot 2.3.0 正式发布!

Spring Data JDBC 使用 Boot 2.3.0 生成错误的 HSQLDB 查询

基于RBAC的SpringCloud分布式权限管理系统