SpringBoot------自定义Redis缓存Cache

SpringBoot自带Cache存在问题:

1.生成Key过于简单,容易冲突 默认为cacheNames + “:” + Key
2.无法设置过期时间,默认时间是永久
3.配置序列化方式,默认是JDKSerializable,可能造成乱码

 自定义Cache分三个步骤:

1.自定义KeyGenerator
2.自定义cacheManager 设置缓存过期时间
3.自定义序列化方式 JackSon

 

1.修改pom.xml文件

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

 

2.添加RedisConfig.java配置

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
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.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.time.Duration;
import java.util.HashMap;
import java.util.Map;

/**
 * @EnableCaching 开启SpringBoot的Cache缓存
 *
 * */
@Configuration
@EnableCaching
public class RedisConfig {
    @Bean
    public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory){

        RedisTemplate<String, String> template = new RedisTemplate<>();
        template.setConnectionFactory(factory);
        return template;
    }

    /**
     * 自定义key值格式
     *
     * */
    @Bean
    public KeyGenerator simpleKeyGenerator(){
        return (o, method, objects) -> {
          StringBuilder builder = new StringBuilder();
          //获取类名称
          builder.append(o.getClass().getSimpleName());
          builder.append(".");
          //获取方法名称
          builder.append(method.getName());
          builder.append("[");
          //遍历方法参数
          for (Object obj : objects){
              builder.append(obj.toString());
          }
          builder.append("]");
          return builder.toString();
        };
    }

    @Bean
    public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory){
        return new RedisCacheManager(
                RedisCacheWriter.lockingRedisCacheWriter(redisConnectionFactory),
                //默认Cache缓存的超时配置
                this.getRedisCacheConfigurationWithTtl(30),
                //自定义Cache缓存Key的超时配置
                this.getRedisCacheConfigurationMap()
        );
    }

    /**
     * 配置自定义Cache缓存Key的超时规则
     *
     * */
    public Map<String, RedisCacheConfiguration> getRedisCacheConfigurationMap(){
        Map<String, RedisCacheConfiguration> redisCacheConfigurationMap = new HashMap<>();
        redisCacheConfigurationMap.put("UserInfoCacheList", this.getRedisCacheConfigurationWithTtl(20));
//        redisCacheConfigurationMap.put("UserInfoCacheAnother", this.getRedisCacheConfigurationWithTtl(30));
        return redisCacheConfigurationMap;
    }

    /**
     * 自定义Cache缓存超时规则
     *
     * */
    public RedisCacheConfiguration getRedisCacheConfigurationWithTtl(Integer seconds){
        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);

        RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig();
                //修改Key的命名规则 默认:cacheName + ":"
//                .computePrefixWith(cacheName -> cacheName.concat(":"))
//                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()));

        redisCacheConfiguration = redisCacheConfiguration.serializeValuesWith(
                RedisSerializationContext
                    .SerializationPair
                    .fromSerializer(jackson2JsonRedisSerializer)
        ).entryTtl(Duration.ofSeconds(seconds));
        return redisCacheConfiguration;
    }
}

 

3.添加Service配置

备注:

只有最后一个是自定义的 前面的是springboot自带的方法

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.theng.shopuser.entity.UserInfo;
import com.theng.shopuser.entity.dto.UserInfoDto;
import com.theng.shopuser.mapper.UserInfoMapper;
import com.theng.shopuser.service.UserInfoService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author tianheng
 * @since 2020-02-09
 */
@Service
@CacheConfig(cacheNames = "userInfoCache")
public class UserInfoService {

    @Autowired
    private UserInfoMapper userInfoMapper;/**
     * 获取缓存中的UserInfo
     * #p0: 对应方法参数 0表示第一个参数
     *
     * */
    @Override
    @Nullable
    @Cacheable(key = "#p0", unless = "#result == null")
    public UserInfo findUserInfoCache(String code){

        return userInfoMapper.findUserInfoByCode(code);
    }

    /**
     * 向缓存中插入UserInfo
     * return: 必须要有返回值 否则无法保存到缓存中
     *
     * */
    @Override
    @CachePut(key = "#p0.userCode")
    public UserInfo insertUserInfoCache(UserInfo userInfo){
        return null;
    }

    /**
     * 向缓存中插入UserInfo
     * return: 必须要有返回值 否则无法保存到缓存中
     *
     * */
    @Override
    @CachePut(key = "#p0.userCode")
    public UserInfo updateUserInfoCache(UserInfo userInfo){
        return null;
    }

    /**
     * 删除cacheNames = "userInfoCache",key值为指定值的缓存
     *
     * */
    @Override
    @CacheEvict(key = "#p0")
    public void deleteUserInfoCache(String userCode){

    }

    /**
     * 清除cacheNames = "userInfoCache"下的所有缓存
     * 如果失败了,则不会清除
     *
     * */
    @Override
    @CacheEvict(allEntries = true)
    public void deleteAllUserInfoCache(){

    }

    @Nullable
    @Cacheable(value = "UserInfoCacheList", keyGenerator = "simpleKeyGenerator")
    public UserInfo customUserInfoCache(){

        return null;
    }
}

 

4.修改controller.java

import com.theng.shopuser.bean.UserSessionBean;
import com.theng.shopuser.entity.UserInfo;
import com.theng.shopuser.service.UserInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/user-info")
public class UserInfoController {

    @Autowired
    private UserInfoService userInfoService;

    //测试
    @GetMapping("/list2")
    public Object getList2() {

        UserInfo userInfo = userInfoService.findUserInfoByCode("YH006");

        return "success";
    }

    @GetMapping("/list3")
    public Object getList3() {
UserInfo userInfo
= userInfoService.customUserInfoCache();
return "success"; } }

 

5.修改pom.xml文件

spring:
  redis:
    database: 0
    host: localhost
    port: 6379
    password:

 

6.输出结果

自定义

 

posted @ 2021-09-23 09:47  玉天恒  阅读(770)  评论(0编辑  收藏  举报