首页 > 其他分享 >Spring Cache的使用

Spring Cache的使用

时间:2024-09-20 21:54:18浏览次数:9  
标签:缓存 return Spring Cache serializer 使用 new public objectMapper

一、简介

1. Spring Cache是Spring提供的一个缓存框架,在Spring3.1版本开始支持将缓存添加到现有的spring应用程序中,在4.1开始,缓存已支持JSR-107注释和更多自定义的选项。

1. Spring Cache利用了**AOP**,实现了基于注解的缓存功能,并且进行了合理的抽象,业务代码不用关心底层是使用了什么缓存框架,**只需要简单地加一个注解,就能实现缓存功能了,做到了对代码侵入性做小。**

1. 由于市面上的缓存工具实在太多,SpringCache框架还提供了CacheManager接口,可以实现降低对各种缓存框架的耦合。它不是具体的缓存实现,它只提供一整套的接口和代码规范、配置、注解等,用于整合各种缓存方案,比如Caffeine、Guava Cache、Ehcache、**Redis**。

二、常用注解

 三、整合Redis

1、pom文件


<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、配置(配置类添加@EnableCaching注解)
 

@Configuration
@EnableCaching
public class CacheConfig extends CachingConfigurerSupport {

    @Resource
    private RedisConnectionFactory factory;


    // 自定义key前缀,例如:cacheName=product.selectOne -> product.selectOne.
    //SEPARATOR=#
    @Bean
    public CacheKeyPrefix cacheKeyPrefix() {
        return cacheName -> cacheName + ".";
    }


    //key生成器
    @Bean
    public KeyGenerator keyGenerator() {
        return (target, method, params) -> {
            StringBuilder sb = new StringBuilder();
            if (ObjectUtil.isBasicType(params[0]) || StrUtil.isEmptyIfStr(params[0])) {
                for (Object param : params) {
                    sb.append(param.toString());//基本类型、字符串类型 key直接拼接
                }
            } else {
                sb.append(JSONUtil.toJsonStr(params[0]));//对象类型拼接json字符串 {}
            }
            return sb.toString();
        };
    }

    @Bean//序列化器
    public Jackson2JsonRedisSerializer<Object> serializer() {
        Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<>(Object.class);
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        objectMapper.configure(MapperFeature.USE_ANNOTATIONS, false);
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
        objectMapper.activateDefaultTyping(objectMapper.getPolymorphicTypeValidator(), ObjectMapper.DefaultTyping.NON_FINAL);
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
        objectMapper.registerModule(new Jdk8Module())
                .registerModule(new JavaTimeModule())
                .registerModule(new ParameterNamesModule());
        serializer.setObjectMapper(objectMapper);
        return serializer;
    }


    @Bean
    public RedisCacheManager redisCacheManager(Jackson2JsonRedisSerializer<Object> serializer) {

        RedisSerializationContext<Object, Object> serializationContext = RedisSerializationContext.fromSerializer(serializer);
        RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration
                .defaultCacheConfig()
                .serializeValuesWith(serializationContext.getValueSerializationPair())//指定redis序列化器
                .computePrefixWith(cacheKeyPrefix());//指定key前缀
        return new CustomRedisCacheManager(RedisCacheWriter.nonLockingRedisCacheWriter(factory), redisCacheConfiguration);

    }


    static class CustomRedisCacheManager extends RedisCacheManager {
        public static final String SEPARATOR = "#";

        public CustomRedisCacheManager(RedisCacheWriter cacheWriter, RedisCacheConfiguration defaultCacheConfiguration) {
            super(cacheWriter, defaultCacheConfiguration);
        }

        @Override
        protected RedisCache createRedisCache(String name, RedisCacheConfiguration cacheConfig) {
            //name=product.selectOne#1800
            String[] arr = StringUtils.delimitedListToStringArray(name, SEPARATOR);
            name = arr[0];//name=product.selectOne
            if (arr.length > 1) {
                long ttl = Long.parseLong(arr[1]);
                cacheConfig = cacheConfig.entryTtl(Duration.ofSeconds(ttl));
            }
            return super.createRedisCache(name, cacheConfig);
        }
    }

}

四、使用

直接在Controller上添加注解

@GetMapping
@Cacheable(value = "product.select#3600")
public List<Product> select(ProductQuery query) {
    return productDao.sel;ect(query);
}


@GetMapping("{id}")
@Cacheable(value = "product.selectById#1800")
public Product selectById(@PathVariable Integer id) {
    return productService.selectOne(id);
}

key示例

五、其他配置

1、缓存击穿配置

@Cacheable(value = "product.selectOne#1800",sync = true)

2、缓存穿透(缓存空值?默认开启) 

#spring.cache.redis.cache-null-values=true

# 配置2(Controller直接配置时间)

 @GetMapping

    @Cacheable(value = "3600")
    public List<Product> select(ProductQuery query) {
        return productDao.select(query);
    }


    @GetMapping("{id}")

    @Cacheable(value = "1800",sync = true)
    public Product selectById(@PathVariable Integer id) {
        return productService.selectOne(id);
    }


@Configuration
@EnableCaching
public class CacheConfig extends CachingConfigurerSupport {


    @Resource
    private RedisConnectionFactory factory;


    // 自定义key前缀,例如:cacheName=product.selectOne -> product.select.
    //SEPARATOR=#
//    @Bean
//    public CacheKeyPrefix cacheKeyPrefix() {
//        return cacheName -> cacheName + "#";
//    }
 

    //key生成器
    @Bean
    public KeyGenerator keyGenerator() {
        return (target, method, params) -> {
            StringBuilder sb = new StringBuilder();
            sb.append(target.getClass().getName()).append(".");
            sb.append(method.getName()).append(".");
            if (ObjectUtil.isBasicType(params[0]) || StrUtil.isEmptyIfStr(params[0])) {
                for (Object param : params) {
                    sb.append(param.toString());//基本类型、字符串类型 key直接拼接
                }
            } else {
                sb.append(JSONUtil.toJsonStr(params[0]));//对象类型拼接json字符串 {}
            }
            return sb.toString();
        };
    }

    @Bean//序列化器
    public Jackson2JsonRedisSerializer<Object> serializer() {
        Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<>(Object.class);
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        objectMapper.configure(MapperFeature.USE_ANNOTATIONS, false);
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
        objectMapper.activateDefaultTyping(objectMapper.getPolymorphicTypeValidator(), ObjectMapper.DefaultTyping.NON_FINAL);
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
        objectMapper.registerModule(new Jdk8Module())
                .registerModule(new JavaTimeModule())
                .registerModule(new ParameterNamesModule());
        serializer.setObjectMapper(objectMapper);
        return serializer;
    }


    @Bean
    public RedisCacheManager redisCacheManager(Jackson2JsonRedisSerializer<Object> serializer) {

        RedisSerializationContext<Object, Object> serializationContext = RedisSerializationContext.fromSerializer(serializer);
        RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration
                .defaultCacheConfig()
                .disableKeyPrefix()//禁用前缀
                .serializeValuesWith(serializationContext.getValueSerializationPair());//指定redis序列化器
                //.computePrefixWith(cacheKeyPrefix()); //指定key前缀cacheable.cacheResolver()

        return new CustomRedisCacheManager(RedisCacheWriter.nonLockingRedisCacheWriter(factory), redisCacheConfiguration);

    }


    static class CustomRedisCacheManager extends RedisCacheManager {
        //public static final String SEPARATOR = "#";

        public CustomRedisCacheManager(RedisCacheWriter cacheWriter, RedisCacheConfiguration defaultCacheConfiguration) {
            super(cacheWriter, defaultCacheConfiguration);
        }

        @Override
        protected RedisCache createRedisCache(String name, RedisCacheConfiguration cacheConfig) {
            //name=product.selectOne#1800
            //String[] arr = StringUtils.delimitedListToStringArray(name, SEPARATOR);
            //if (arr.length > 1) {
                long ttl = Long.parseLong(name);
                cacheConfig = cacheConfig.entryTtl(Duration.ofSeconds(ttl));
            //}
            return super.createRedisCache(name, cacheConfig);
        }
    }

}

标签:缓存,return,Spring,Cache,serializer,使用,new,public,objectMapper
From: https://blog.csdn.net/zhzjn/article/details/142406286

相关文章

  • 使用MPlayer播放音视频
    目录一、MPlayer简介二、MPlayer的安装1.在Linux上安装2.在Windows上安装3.在macOS上安装三、MPlayer的基本用法1.播放本地文件2.播放网络视频流3.播放DVD四、常用选项和参数1.全屏播放2.指定音频/视频输出设备3.调整音量和亮度4.控制播放速度......
  • 毕业设计选题:151基于springboot+vue的校园志愿者管理系统
     开发语言:Java框架:springbootJDK版本:JDK1.8服务器:tomcat7数据库:mysql5.7(一定要5.7版本)数据库工具:Navicat11开发软件:eclipse/myeclipse/ideaMaven包:Maven3.3.9系统展示系统首页用户注册活动信息活动心得个人中心管理员登录管理员功能志愿者管理活动类型管理......
  • JUnit 与 Mockito:了解差异以及如何一起使用它们
    当谈到Java生态系统中的测试时,有两个框架脱颖而出:JUnit和Mockito。两者都是开发人员工具包中的必备工具,但它们有不同的用途。在这篇文章中,我们将深入探讨JUnit和Mockito之间的差异,探索它们如何相互补充,并讨论一起使用它们的最佳实践。什么是JUnit?JUnit是一个功能强大的测......
  • SSMspringbmvc餐厅点餐ut4b3 购物车
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表系统内容:用户,美食类型,特色美食开题报告内容一、项目背景与意义随着信息技术的飞速发展,餐饮业正逐步向数字化、智能化转型。传统的餐厅点餐方式存在效率低下......
  • 使用opencv画框,标出坐标
    importcv2importnumpyasnpdrawing,start_x,start_y=False,-1,-1prev_point=None#上一个点history=list()defdraw_box(points,color=(0,255,0),thickness=1):ifpoints:p1,p2=pointstop_left,top_right,bottom_right,b......
  • 使用U盘PE重装Windows系统
    1、概述操作系统一般都是安装在硬盘内的,硬盘是一种存储数据的介质,U盘同样也是一种存储数据的介质,因此也可以把操作系统安装进U盘里。因为大部分U盘的性能比较差,不能流畅地运行完整版的操作系统,所以只能安装精简了大部分功能、只保留基本运行环境的简化版操作系统(即PE)。P......
  • 使用Code-Prompt模拟实现openai o1: V2
    在之前的一个版本中,展现出来一定的思考能力,但是这只是一种表演型的思考能力,为什么?根据实际的观察,我认为是因为规划的部分,这部分实际上是有问题的,将后续的Step限制的太严重了.改进思路其实在上一期已经提过了,那就是怎么思考,思考不是能够在一开始就就能够规划好......
  • CompletableFuture使用示例
    CompletableFuture是Java8中引入的一个功能强大的类,它实现了Future和CompletionStage两个接口,主要用于异步编程。通过它,开发者可以以一种非阻塞的方式编写异步代码,从而提高程序的响应速度和资源利用率。异步执行:CompletableFuture支持在后台线程中异步执行计算或操作,避免阻塞主线......
  • SpringBoot整合Mybatis-flex
    第1步:创建数据库表CREATETABLEIFNOTEXISTS`tb_account`(`id`INTEGERPRIMARYKEYauto_increment,`user_name`VARCHAR(100),`age`INTEGER,`birthday`DATETIME);INSERTINTOtb_account(id,user_name,age,birthday)VALUE......
  • Lichee NanoKVM基本使用环境.18423052
    LicheeNanoKVM基本使用环境本文章主要记录一些自己在初期的使用,以及自己的一些经验,非常感谢sipeedNanoKVM官方使用教程外观(博主自己的是lite版本,非常感谢sipeed)LicheeNanoKVM是基于LicheeRVNano的IP-KVM产品,继承了LicheeRVNano的极致体积和强大功能。NanoKVM......