• 【7】Spring Boot 3 集成组件:缓存组件 spring cache + spring data redis


    个人主页: 【⭐️个人主页
    需要您的【💖 点赞+关注】支持 💯


    【7】Spring Boot 3 集成组件:缓存组件 spring cache + spring data redis

    📖 本文核心知识点:

    • spring cache 抽象和注解
    • cache 支持的缓存类型
    • spring cache + spring data redis 配置
    • redis序列化

    本章使用的spring版本
    spring boot version: 3.1.5

    什么是缓存抽象

    1. 缓存抽象的作用
    2. spring缓存的声明式注解
    3. spring缓存的生成key策略和如何自定义keyGenerator
    4. 缓存支持的后端类型

    声明式注解

    Spring 缓存注解说明
    @Cacheable触发缓存填充。
    @CacheEvict触发缓存退出。
    @CachePut在不干扰方法执行的情况下更新缓存。
    @Caching将多个缓存操作重新组合到一个方法上。
    @CacheConfig在类级别共享一些常见的与缓存相关的设置。

    JSR-107对应

    Spring 缓存注解JSR-107备注
    @Cacheable@CacheResult相当相似。 可以缓存特定的异常并强制 无论缓存的内容如何,都执行该方法。@CacheResult
    @CachePut@CachePut当 Spring 使用方法调用的结果更新缓存时,JCache 要求将其作为注释的参数传递。 由于这种差异,JCache 允许在 实际方法调用。@CacheValue
    @CacheEvict@CacheRemove相当相似。 支持有条件逐出,当 方法调用会导致异常。@CacheRemove
    @CacheEvict(allEntries=true)@CacheRemoveAll看。@CacheRemove
    @CacheConfig@CacheDefaults允许您以类似的方式配置相同的概念。

    SpEL上下文数据

    名称位置描述示例
    methodNameroot对象当前被调用的方法名#root.methodname
    methodroot对象当前被调用的方法#root.method.name
    targetroot对象当前被调用的目标对象实例#root.target
    targetClassroot对象当前被调用的目标对象的类#root.targetClass
    argsroot对象当前被调用的方法的参数列表#root.args[0]
    cachesroot对象当前方法调用使用的缓存列表#root.caches[0].name
    Argument Name执行上下文当前被调用的方法的参数,如findArtisan(Artisan artisan),可以通过#artsian.id获得参数#artsian.id
    result执行上下文方法执行后的返回值(仅当方法执行后的判断有效,如 unless cacheEvict的beforeInvocation=false)#result

    引入依赖

        implementation 'org.springframework.boot:spring-boot-starter-cache'
    
    • 1

    添加启用缓存注解@EnableCaching

    @SpringBootApplication(scanBasePackages = {"com.kongxiang"})
    @EnableAutoConfiguration
    @EnableCaching
    public class StudySpring3Application {
    
    	public static void main(String[] args) {
    		SpringApplication.run(StudySpring3Application.class, args);
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    cache 支持的缓存类型

    spring cache支持的缓存类型
    查看类org.springframework.boot.autoconfigure.cache.CacheType

    public enum CacheType {
    
    	/**
    	 * Generic caching using 'Cache' beans from the context.
    	 */
    	GENERIC,
    
    	/**
    	 * JCache (JSR-107) backed caching.
    	 */
    	JCACHE,
    
    	/**
    	 * Hazelcast backed caching.
    	 */
    	HAZELCAST,
    
    	/**
    	 * Couchbase backed caching.
    	 */
    	COUCHBASE,
    
    	/**
    	 * Infinispan backed caching.
    	 */
    	INFINISPAN,
    
    	/**
    	 * Redis backed caching.
    	 */
    	REDIS,
    
    	/**
    	 * Cache2k backed caching.
    	 */
    	CACHE2K,
    
    	/**
    	 * Caffeine backed caching.
    	 */
    	CAFFEINE,
    
    	/**
    	 * Simple in-memory caching.
    	 */
    	SIMPLE,
    
    	/**
    	 * No caching.
    	 */
    	NONE
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53

    缓存类型配置

    NONE

    无缓存

    spring:
      cache:
        type: NONE
    
    
    • 1
    • 2
    • 3
    • 4

    SIMPLE

    内存缓存

    spring:
      cache:
        type: SIMPLE
    
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述

    REDIS

    Redis 缓存

    spring:
      cache:
        type: REDIS
      data:
        redis:
          host: '127.0.0.1'
          username:
          port: 6379
          password:
          database: 1
          lettuce:
            pool:
              enabled: true
              max-active: 8
              max-wait: 1000
              max-idle: 8
          connect-timeout: 5000
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    自定义配置

    默认情况下会有两个模板类被注入Spring IoC供我们使用,需要个性化配置来满足实际的开发。

    一个是RedisTemplate,主要用于对象缓存,其默认使用JDK序列化,我们需要更改其序列化方式解决一些问题,比如Java 8日期问题JSON序列化问题。需要我们重写一下。

    1. RedisTemplate自定义配置
     @Bean
        public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory factory) {
            RedisTemplate<Object, Object> template = new RedisTemplate<>();
            template.setConnectionFactory(factory);
            // 使用Jackson2JsonRedisSerialize 替换默认序列化
            Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = initJacksonSerializer();
            // 设置value的序列化规则和 key的序列化规则
            template.setValueSerializer(jackson2JsonRedisSerializer);
            template.setKeySerializer(new StringRedisSerializer());
            template.afterPropertiesSet();
            return template;
        }
        /**
         * 处理redis序列化问题
         * @return Jackson2JsonRedisSerializer
         */
        private Jackson2JsonRedisSerializer<Object> initJacksonSerializer() {
            ObjectMapper om = new ObjectMapper();
            om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
            //以下替代旧版本 om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
            om.activateDefaultTyping(om.getPolymorphicTypeValidator(), ObjectMapper.DefaultTyping.NON_FINAL);
            //bugFix Jackson2反序列化数据处理LocalDateTime类型时出错
            om.disable(SerializationFeature.WRITE_DATE_KEYS_AS_TIMESTAMPS);
            // java8 时间支持
            om.registerModule(new JavaTimeModule());
            return new Jackson2JsonRedisSerializer<>(om,Object.class);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    1. 缓存管理器自定义配置
      使用Spring Cache做缓存的时候,有针对不同的key设置不同过期时间的场景。比如Jwt Token我想设置为一周过期,而验证码我想设置为五分钟过期。这个怎么实现呢?需要我们个性化配置RedisCacheManager。首先我通过枚举来定义这些缓存及其TTL时间

    我们通过向Spring IoC分别注入RedisCacheConfigurationRedisCacheManagerBuilderCustomizer来个性化配置

    
     /**
         * Redis cache configuration.
         *
         * @param redisTemplate the redis template
         * @return the redis cache configuration
         */
        @Bean
        public RedisCacheConfiguration redisCacheConfiguration(RedisTemplate<Object, Object> redisTemplate, CacheProperties cacheProperties) {
            // 参见 spring.cache.redis
            CacheProperties.Redis redisProperties = cacheProperties.getRedis();
    
            RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
                    // 缓存的序列化问题
                    .serializeValuesWith(RedisSerializationContext.SerializationPair
                            .fromSerializer(redisTemplate.getValueSerializer()));
    
            if (redisProperties.getTimeToLive() != null) {
                // 全局 TTL 时间
                redisCacheConfiguration = redisCacheConfiguration.entryTtl(redisProperties.getTimeToLive());
            }
            if (redisProperties.getKeyPrefix() != null) {
                // key 前缀值
                redisCacheConfiguration = redisCacheConfiguration.prefixCacheNameWith(redisProperties.getKeyPrefix());
            }
            if (!redisProperties.isCacheNullValues()) {
                // 默认缓存null值 可以防止缓存穿透
                redisCacheConfiguration = redisCacheConfiguration.disableCachingNullValues();
            }
            if (!redisProperties.isUseKeyPrefix()) {
                // 不使用key前缀
                redisCacheConfiguration = redisCacheConfiguration.disableKeyPrefix();
            }
            return redisCacheConfiguration;
        }
    
        /**
         * Redis cache manager 个性化配置缓存过期时间.
         *
         * @return the redis cache manager builder customizer
         */
        @Bean
        public RedisCacheManagerBuilderCustomizer redisCacheManagerBuilderCustomizer(RedisCacheConfiguration redisCacheConfiguration) {
            return builder -> builder.cacheDefaults(redisCacheConfiguration);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    CAFFEINE

    引入依赖

        implementation 'com.github.ben-manes.caffeine:caffeine:3.1.8'
    
    • 1

    修改配置

    spring:
      cache:
        type: CAFFEINE
    
    • 1
    • 2
    • 3

    直接启动即可

    Hazelcast

    总结

    spring cache 缓存抽象加上spring data包和spring boot autoconfig 配置包的能力,可以快速接入一个具体的缓存实现。redis是我们公司基本使用的缓存策略。所以针对redis的一些自定义配置,通过 java bean的方式实现。着重强调一下。

  • 相关阅读:
    vue项目获取视频封面展示在页面上
    uniapp地图围栏代码
    halcon模板匹配捆绑测量矩形检测芯片针脚
    正则表达式
    程序员福音,关于如何使用Markdown写出一份漂亮的简历 —— 程序员简历 | md文档简历制作教程
    30个Python常用极简代码,拿走就用
    腾讯云 Web 超级播放器开发实战
    2020年9月大学英语六级作文
    OpenCV图像处理——(实战)信用卡识别
    李宏毅机器学习|图神经网络Graph Nerual Networks(GNN)|学习笔记-part1
  • 原文地址:https://blog.csdn.net/k316378085/article/details/134433184