4.基于redis缓存配置

本文介绍如何在Spring应用中配置Redis作为缓存存储,并通过示例展示如何自定义缓存键生成器及设置缓存过期时间等高级特性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.配置类

@Configuration
@EnableCaching
public class RedisConfigurer extends CachingConfigurerSupport {
    @Bean
    public KeyGenerator keyGenerator() {
        return new KeyGenerator() {
            @Override
            public Object generate(Object targetMethod methodObject... params) {
                StringBuilder sb = new StringBuilder();
                String className = target.getClass().getName().replace("com.duia.home.service.impl.","").replace("ServiceImpl","");
                sb.append(className+".");
                sb.append(method.getName()+".");
                for (Object obj : params) {
                    if (obj instanceof Date){
                        sb.append( DateUtils.format((Date) obj,"yyyy-MM-dd"));
                    }else {
                        sb.append (obj.toString());
                    }

                }
                return sb.toString();
            }
        };
    }

    @Bean
    public CacheManager cacheManager(@SuppressWarnings("rawtypes") RedisTemplate<??> redisTemplate) {
        // 创建缓存管理器
        ArrayList<String> cacheNames = new ArrayList<>();
        cacheNames.add("home");
        RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate,cacheNames);
        cacheManager.setDefaultExpiration(3600*24);
        cacheManager.setUsePrefix(true);
        cacheManager.setCachePrefix(new DefaultRedisCachePrefix(":"));
        return cacheManager;
    }

    @Bean
    public RedisTemplate<StringString> redisTemplate(RedisConnectionFactory factory) {
        StringRedisTemplate template = new StringRedisTemplate(factory);
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALLJsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        template.setValueSerializer(jackson2JsonRedisSerializer);
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        template.afterPropertiesSet();
        return template;
    }


}



2.使用实例

@Cacheable(value = "usercache",keyGenerator = "keyGenerator")
public List<CourseLiveNewDto> findTodayOpenLivesBySku(Integer sku, Date now, Integer flag) {

}

3.结构图




3.源码分析

一.服务启动,当properties加载完后,将缓存管理器里(如redis库)的数据放到内存中

1.先执行3中的public void afterPropertiesSet() {this.initializeCaches();}
public void initializeCaches() {
    Collection caches = this.loadCaches();
    synchronized(this.cacheMap) {
            ....
        while(var4.hasNext()) {
            ...
            this.cacheMap.put(name, this.decorateCache(cache));
            cacheNames.add(name);
        }
    }
}

3.先执行5的loadCaches

protected Collection<? extends Cache> loadCaches() {
    Set caches = new Set((Collection)(this.loadRemote?this.loadAndInit():new ArrayList()));//从redis中获取key
               ...
            caches.add(this.createCache(cacheName));//从redis中获取k-v值
        }
    }
    return caches;
}


protected RedisCache createCache(String cacheName) {
    long expiration = this.computeExpiration(cacheName);
    return new RedisCache(cacheName, this.usePrefix?this.cachePrefix.prefix(cacheName):null, this.redisOperations, expiration, this.cacheNullValues);
}


二.第一次请求service

1.执行5的getCache
public Cache getCache(String name) {
    Cache cache = (Cache)this.cacheMap.get(name);//从内存中取name的值
    if(cache != null) {
        return cache;
    } else {
      。...

            return cache;
        }
    }
}

2.放开执行方法返回时启动CacheAspectSupport切面类方法execute将结果保存到redis和内存中
private Object execute(...) {
         ....
        returnValue = this.invokeOperation(invoker);
        cacheValue = this.unwrapReturnValue(returnValue);
        ....
        cachePutRequest.apply(cacheValue);
        return returnValue;
    }
}


public void apply(Object result) {
    if(this.context.canPutToCache(result)) {
        Iterator var2 = this.context.getCaches().iterator();
        while(var2.hasNext()) {
            Cache cache = (Cache)var2.next();
            CacheAspectSupport.this.doPut(cache, this.key, result);
        }
    }

}


3.构造RedisCache

public void put(Object key, Object value) {
    this.put((new RedisCacheElement(this.getRedisCacheKey(key), this.toStoreValue(value))).expireAfter(this.cacheMetadata.getDefaultExpiration()));
}


private RedisCacheKey getRedisCacheKey(Object key) {
    return (new RedisCacheKey(key)).usePrefix(this.cacheMetadata.getKeyPrefix()).withKeySerializer(this.redisOperations.getKeySerializer());
}


public byte[] prefix(String cacheName) {
    return this.serializer.serialize(this.delimiter != null?cacheName.concat(this.delimiter):cacheName.concat(":"));
}



4.从缓存中读取

public Cache getCache(String name) {
    Cache cache = (Cache)this.cacheMap.get(name);//从内存中取name的值
    if(cache != null) {
        return cache;
    } else {
      。...

            return cache;
        }
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值