Spring Boot缓存机制详解

文章目录

    • [1. 缓存概述](#1. 缓存概述)
      • [1.1 缓存类型](#1.1 缓存类型)
      • [1.2 缓存策略](#1.2 缓存策略)
      • [1.3 核心依赖](#1.3 核心依赖)
    • [2. Spring Cache注解](#2. Spring Cache注解)
      • [2.1 基础缓存注解](#2.1 基础缓存注解)
      • [2.2 条件缓存](#2.2 条件缓存)
    • [3. 缓存配置](#3. 缓存配置)
      • [3.1 基础缓存配置](#3.1 基础缓存配置)
      • [3.2 Caffeine缓存配置](#3.2 Caffeine缓存配置)
      • [3.3 Redis缓存配置](#3.3 Redis缓存配置)
    • [4. 多级缓存](#4. 多级缓存)
      • [4.1 多级缓存实现](#4.1 多级缓存实现)
      • [4.2 缓存预热](#4.2 缓存预热)
    • [5. 缓存监控](#5. 缓存监控)
      • [5.1 缓存统计](#5.1 缓存统计)
      • [5.2 缓存监控端点](#5.2 缓存监控端点)
    • [6. 缓存策略](#6. 缓存策略)
      • [6.1 缓存更新策略](#6.1 缓存更新策略)
      • [6.2 缓存一致性](#6.2 缓存一致性)
    • [7. 缓存性能优化](#7. 缓存性能优化)
      • [7.1 缓存预热](#7.1 缓存预热)
      • [7.2 缓存压缩](#7.2 缓存压缩)
    • [8. 缓存配置优化](#8. 缓存配置优化)
      • [8.1 配置文件](#8.1 配置文件)
      • [8.2 高级缓存配置](#8.2 高级缓存配置)
    • [9. 总结](#9. 总结)

1. 缓存概述

缓存是提高应用性能的重要手段,Spring Boot提供了完整的缓存解决方案。通过缓存可以减少数据库访问、提高响应速度、降低系统负载。

1.1 缓存类型

  • 本地缓存:JVM内存中的缓存,速度快但容量有限
  • 分布式缓存:Redis、Memcached等,支持集群部署
  • 数据库缓存:查询结果缓存、连接池缓存
  • HTTP缓存:浏览器缓存、CDN缓存

1.2 缓存策略

  • Cache-Aside:应用程序管理缓存
  • Read-Through:缓存自动从数据源读取
  • Write-Through:同时写入缓存和数据源
  • Write-Behind:异步写入数据源

1.3 核心依赖

xml 复制代码
<dependencies>
    <!-- Spring Boot Cache -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-cache</artifactId>
    </dependency>
    
    <!-- Spring Boot Data Redis -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    
    <!-- Caffeine Cache -->
    <dependency>
        <groupId>com.github.ben-manes.caffeine</groupId>
        <artifactId>caffeine</artifactId>
    </dependency>
    
    <!-- EhCache -->
    <dependency>
        <groupId>org.ehcache</groupId>
        <artifactId>ehcache</artifactId>
    </dependency>
</dependencies>

2. Spring Cache注解

2.1 基础缓存注解

java 复制代码
package com.example.demo.service;

import com.example.demo.entity.User;
import com.example.demo.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Caching;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Optional;

@Service
public class UserCacheService {
    
    @Autowired
    private UserRepository userRepository;
    
    // 缓存查询结果
    @Cacheable(value = "users", key = "#id")
    public Optional<User> findById(Long id) {
        System.out.println("从数据库查询用户: " + id);
        return userRepository.findById(id);
    }
    
    // 缓存用户列表
    @Cacheable(value = "userList", key = "#status")
    public List<User> findByStatus(String status) {
        System.out.println("从数据库查询用户列表: " + status);
        return userRepository.findByStatus(status);
    }
    
    // 更新缓存
    @CachePut(value = "users", key = "#user.id")
    public User save(User user) {
        System.out.println("保存用户到数据库: " + user.getUsername());
        return userRepository.save(user);
    }
    
    // 清除缓存
    @CacheEvict(value = "users", key = "#id")
    public void deleteById(Long id) {
        System.out.println("从数据库删除用户: " + id);
        userRepository.deleteById(id);
    }
    
    // 清除所有用户缓存
    @CacheEvict(value = "users", allEntries = true)
    public void clearAllUserCache() {
        System.out.println("清除所有用户缓存");
    }
    
    // 组合缓存操作
    @Caching(
        evict = {
            @CacheEvict(value = "users", key = "#user.id"),
            @CacheEvict(value = "userList", allEntries = true)
        }
    )
    public User updateUser(User user) {
        System.out.println("更新用户: " + user.getUsername());
        return userRepository.save(user);
    }
}

2.2 条件缓存

java 复制代码
package com.example.demo.service;

import com.example.demo.entity.User;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Service;

@Service
public class ConditionalCacheService {
    
    // 条件缓存:只有活跃用户才缓存
    @Cacheable(value = "activeUsers", condition = "#user.status == 'ACTIVE'")
    public User cacheActiveUser(User user) {
        System.out.println("缓存活跃用户: " + user.getUsername());
        return user;
    }
    
    // 条件清除:只有特定状态才清除
    @CacheEvict(value = "users", condition = "#user.status == 'INACTIVE'")
    public void evictInactiveUser(User user) {
        System.out.println("清除非活跃用户缓存: " + user.getUsername());
    }
    
    // 条件更新:只有特定条件才更新缓存
    @CachePut(value = "users", unless = "#result == null")
    public User updateUserConditionally(User user) {
        if (user.getId() == null) {
            return null; // 不缓存null结果
        }
        return user;
    }
}

3. 缓存配置

3.1 基础缓存配置

java 复制代码
package com.example.demo.config;

import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.concurrent.ConcurrentMapCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@EnableCaching
public class CacheConfig {
    
    @Bean
    public CacheManager cacheManager() {
        ConcurrentMapCacheManager cacheManager = new ConcurrentMapCacheManager();
        cacheManager.setCacheNames("users", "userList", "activeUsers");
        return cacheManager;
    }
}

3.2 Caffeine缓存配置

java 复制代码
package com.example.demo.config;

import com.github.benmanes.caffeine.cache.Caffeine;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.caffeine.CaffeineCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.concurrent.TimeUnit;

@Configuration
@EnableCaching
public class CaffeineCacheConfig {
    
    @Bean
    public CacheManager cacheManager() {
        CaffeineCacheManager cacheManager = new CaffeineCacheManager();
        cacheManager.setCaffeine(Caffeine.newBuilder()
                .maximumSize(1000)
                .expireAfterWrite(10, TimeUnit.MINUTES)
                .expireAfterAccess(5, TimeUnit.MINUTES)
                .recordStats());
        return cacheManager;
    }
}

3.3 Redis缓存配置

java 复制代码
package com.example.demo.config;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
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.connection.RedisConnectionFactory;
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;

@Configuration
public class RedisCacheConfig {
    
    @Bean
    public CacheManager cacheManager(RedisConnectionFactory connectionFactory) {
        // 配置序列化
        Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<>(Object.class);
        ObjectMapper mapper = new ObjectMapper();
        mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        mapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL);
        serializer.setObjectMapper(mapper);
        
        // 配置缓存
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofMinutes(10))
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(serializer))
                .disableCachingNullValues();
        
        return RedisCacheManager.builder(connectionFactory)
                .cacheDefaults(config)
                .build();
    }
}

4. 多级缓存

4.1 多级缓存实现

java 复制代码
package com.example.demo.service;

import com.example.demo.entity.User;
import com.example.demo.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

@Service
public class MultiLevelCacheService {
    
    @Autowired
    private UserRepository userRepository;
    
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    
    private static final String REDIS_KEY_PREFIX = "user:";
    private static final long REDIS_EXPIRE_TIME = 30; // 30分钟
    
    // L1缓存:本地缓存
    @Cacheable(value = "localUsers", key = "#id")
    public Optional<User> getUserFromL1Cache(Long id) {
        System.out.println("L1缓存未命中,查询L2缓存");
        return getUserFromL2Cache(id);
    }
    
    // L2缓存:Redis缓存
    public Optional<User> getUserFromL2Cache(Long id) {
        String redisKey = REDIS_KEY_PREFIX + id;
        User user = (User) redisTemplate.opsForValue().get(redisKey);
        
        if (user != null) {
            System.out.println("L2缓存命中: " + id);
            return Optional.of(user);
        }
        
        System.out.println("L2缓存未命中,查询数据库");
        return getUserFromDatabase(id);
    }
    
    // L3缓存:数据库
    public Optional<User> getUserFromDatabase(Long id) {
        System.out.println("从数据库查询用户: " + id);
        Optional<User> user = userRepository.findById(id);
        
        if (user.isPresent()) {
            // 写入L2缓存
            String redisKey = REDIS_KEY_PREFIX + id;
            redisTemplate.opsForValue().set(redisKey, user.get(), REDIS_EXPIRE_TIME, TimeUnit.MINUTES);
        }
        
        return user;
    }
}

4.2 缓存预热

java 复制代码
package com.example.demo.service;

import com.example.demo.entity.User;
import com.example.demo.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.util.List;

@Service
public class CacheWarmupService {
    
    @Autowired
    private UserRepository userRepository;
    
    @Autowired
    private UserCacheService userCacheService;
    
    @PostConstruct
    public void warmupCache() {
        System.out.println("开始缓存预热...");
        
        // 预热活跃用户缓存
        List<User> activeUsers = userRepository.findByStatus("ACTIVE");
        for (User user : activeUsers) {
            userCacheService.findById(user.getId());
        }
        
        System.out.println("缓存预热完成,预热了 " + activeUsers.size() + " 个用户");
    }
}

5. 缓存监控

5.1 缓存统计

java 复制代码
package com.example.demo.service;

import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.stats.CacheStats;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.CacheManager;
import org.springframework.cache.caffeine.CaffeineCache;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Map;

@Service
public class CacheStatsService {
    
    @Autowired
    private CacheManager cacheManager;
    
    public Map<String, Object> getCacheStats() {
        Map<String, Object> stats = new HashMap<>();
        
        cacheManager.getCacheNames().forEach(cacheName -> {
            CaffeineCache caffeineCache = (CaffeineCache) cacheManager.getCache(cacheName);
            if (caffeineCache != null) {
                Cache<Object, Object> nativeCache = caffeineCache.getNativeCache();
                CacheStats cacheStats = nativeCache.stats();
                
                Map<String, Object> cacheStatsMap = new HashMap<>();
                cacheStatsMap.put("hitCount", cacheStats.hitCount());
                cacheStatsMap.put("missCount", cacheStats.missCount());
                cacheStatsMap.put("hitRate", cacheStats.hitRate());
                cacheStatsMap.put("evictionCount", cacheStats.evictionCount());
                cacheStatsMap.put("size", nativeCache.estimatedSize());
                
                stats.put(cacheName, cacheStatsMap);
            }
        });
        
        return stats;
    }
}

5.2 缓存监控端点

java 复制代码
package com.example.demo.controller;

import com.example.demo.service.CacheStatsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;

@RestController
@RequestMapping("/api/cache")
public class CacheController {
    
    @Autowired
    private CacheStatsService cacheStatsService;
    
    @GetMapping("/stats")
    public Map<String, Object> getCacheStats() {
        return cacheStatsService.getCacheStats();
    }
}

6. 缓存策略

6.1 缓存更新策略

java 复制代码
package com.example.demo.service;

import com.example.demo.entity.User;
import com.example.demo.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class CacheUpdateStrategyService {
    
    @Autowired
    private UserRepository userRepository;
    
    // 写回策略:同时更新缓存和数据库
    @CachePut(value = "users", key = "#user.id")
    @Transactional
    public User writeThrough(User user) {
        System.out.println("写回策略:同时更新缓存和数据库");
        return userRepository.save(user);
    }
    
    // 写分配策略:先更新数据库,再更新缓存
    @Transactional
    public User writeAllocate(User user) {
        System.out.println("写分配策略:先更新数据库");
        User savedUser = userRepository.save(user);
        
        // 手动更新缓存
        updateCache(savedUser);
        
        return savedUser;
    }
    
    // 写不分配策略:只更新数据库,清除缓存
    @CacheEvict(value = "users", key = "#user.id")
    @Transactional
    public User writeNoAllocate(User user) {
        System.out.println("写不分配策略:只更新数据库,清除缓存");
        return userRepository.save(user);
    }
    
    // 异步写回策略
    @Transactional
    public User writeBehind(User user) {
        System.out.println("异步写回策略:先更新缓存,异步更新数据库");
        updateCache(user);
        
        // 异步更新数据库
        asyncUpdateDatabase(user);
        
        return user;
    }
    
    private void updateCache(User user) {
        // 实现缓存更新逻辑
    }
    
    private void asyncUpdateDatabase(User user) {
        // 实现异步数据库更新逻辑
    }
}

6.2 缓存一致性

java 复制代码
package com.example.demo.service;

import com.example.demo.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import java.util.concurrent.TimeUnit;

@Service
public class CacheConsistencyService {
    
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    
    // 强一致性:使用分布式锁
    public User updateUserWithLock(User user) {
        String lockKey = "lock:user:" + user.getId();
        String lockValue = String.valueOf(System.currentTimeMillis());
        
        try {
            // 获取分布式锁
            Boolean lockAcquired = redisTemplate.opsForValue()
                    .setIfAbsent(lockKey, lockValue, 30, TimeUnit.SECONDS);
            
            if (lockAcquired) {
                // 更新数据库
                updateDatabase(user);
                
                // 更新缓存
                updateCache(user);
                
                return user;
            } else {
                throw new RuntimeException("获取锁失败");
            }
        } finally {
            // 释放锁
            releaseLock(lockKey, lockValue);
        }
    }
    
    // 最终一致性:使用消息队列
    public User updateUserWithMQ(User user) {
        // 更新数据库
        updateDatabase(user);
        
        // 发送缓存更新消息
        sendCacheUpdateMessage(user);
        
        return user;
    }
    
    private void updateDatabase(User user) {
        // 实现数据库更新逻辑
    }
    
    private void updateCache(User user) {
        // 实现缓存更新逻辑
    }
    
    private void sendCacheUpdateMessage(User user) {
        // 实现消息发送逻辑
    }
    
    private void releaseLock(String lockKey, String lockValue) {
        // 实现锁释放逻辑
    }
}

7. 缓存性能优化

7.1 缓存预热

java 复制代码
package com.example.demo.service;

import com.example.demo.entity.User;
import com.example.demo.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.concurrent.CompletableFuture;

@Service
public class CacheWarmupService {
    
    @Autowired
    private UserRepository userRepository;
    
    @Autowired
    private UserCacheService userCacheService;
    
    // 异步预热缓存
    @Async
    public CompletableFuture<Void> warmupCacheAsync() {
        System.out.println("开始异步缓存预热...");
        
        List<User> users = userRepository.findAll();
        for (User user : users) {
            userCacheService.findById(user.getId());
        }
        
        System.out.println("异步缓存预热完成");
        return CompletableFuture.completedFuture(null);
    }
    
    // 分批预热缓存
    public void warmupCacheInBatches(int batchSize) {
        System.out.println("开始分批缓存预热...");
        
        List<User> users = userRepository.findAll();
        for (int i = 0; i < users.size(); i += batchSize) {
            int endIndex = Math.min(i + batchSize, users.size());
            List<User> batch = users.subList(i, endIndex);
            
            for (User user : batch) {
                userCacheService.findById(user.getId());
            }
            
            System.out.println("预热批次 " + (i / batchSize + 1) + " 完成");
        }
        
        System.out.println("分批缓存预热完成");
    }
}

7.2 缓存压缩

java 复制代码
package com.example.demo.service;

import com.example.demo.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

@Service
public class CacheCompressionService {
    
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    
    // 压缩存储
    public void storeCompressed(String key, User user) {
        try {
            byte[] compressed = compress(user);
            redisTemplate.opsForValue().set(key, compressed);
        } catch (Exception e) {
            throw new RuntimeException("压缩存储失败", e);
        }
    }
    
    // 解压读取
    public User getCompressed(String key) {
        try {
            byte[] compressed = (byte[]) redisTemplate.opsForValue().get(key);
            if (compressed != null) {
                return decompress(compressed);
            }
            return null;
        } catch (Exception e) {
            throw new RuntimeException("解压读取失败", e);
        }
    }
    
    private byte[] compress(User user) throws Exception {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        GZIPOutputStream gzos = new GZIPOutputStream(baos);
        ObjectOutputStream oos = new ObjectOutputStream(gzos);
        oos.writeObject(user);
        oos.close();
        return baos.toByteArray();
    }
    
    private User decompress(byte[] compressed) throws Exception {
        ByteArrayInputStream bais = new ByteArrayInputStream(compressed);
        GZIPInputStream gzis = new GZIPInputStream(bais);
        ObjectInputStream ois = new ObjectInputStream(gzis);
        User user = (User) ois.readObject();
        ois.close();
        return user;
    }
}

8. 缓存配置优化

8.1 配置文件

yaml 复制代码
# application.yml
spring:
  cache:
    type: caffeine
    caffeine:
      spec: maximumSize=1000,expireAfterWrite=10m,expireAfterAccess=5m
    redis:
      time-to-live: 600000 # 10分钟
      cache-null-values: false
      use-key-prefix: true
      key-prefix: "cache:"
  
  redis:
    host: localhost
    port: 6379
    password: 
    database: 0
    timeout: 2000ms
    lettuce:
      pool:
        max-active: 8
        max-idle: 8
        min-idle: 0
        max-wait: -1ms

# 缓存监控
management:
  endpoints:
    web:
      exposure:
        include: cache,health,metrics
  endpoint:
    cache:
      enabled: true
  metrics:
    export:
      prometheus:
        enabled: true

8.2 高级缓存配置

java 复制代码
package com.example.demo.config;

import com.github.benmanes.caffeine.cache.Caffeine;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.caffeine.CaffeineCacheManager;
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.connection.RedisConnectionFactory;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
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;

@Configuration
@EnableCaching
public class AdvancedCacheConfig {
    
    @Bean
    public CacheManager cacheManager(RedisConnectionFactory connectionFactory) {
        // 配置不同的缓存策略
        Map<String, RedisCacheConfiguration> cacheConfigurations = new HashMap<>();
        
        // 用户缓存:10分钟过期
        cacheConfigurations.put("users", RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofMinutes(10))
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer())));
        
        // 用户列表缓存:5分钟过期
        cacheConfigurations.put("userList", RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofMinutes(5))
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer())));
        
        // 活跃用户缓存:30分钟过期
        cacheConfigurations.put("activeUsers", RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofMinutes(30))
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer())));
        
        return RedisCacheManager.builder(connectionFactory)
                .cacheDefaults(RedisCacheConfiguration.defaultCacheConfig()
                        .entryTtl(Duration.ofMinutes(10))
                        .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
                        .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer())))
                .withInitialCacheConfigurations(cacheConfigurations)
                .build();
    }
}

9. 总结

Spring Boot缓存机制提供了完整的缓存解决方案:

  1. 缓存注解:@Cacheable、@CachePut、@CacheEvict等
  2. 缓存配置:支持多种缓存实现(Caffeine、Redis、EhCache)
  3. 多级缓存:本地缓存+分布式缓存
  4. 缓存监控:缓存统计和性能监控
  5. 缓存策略:多种缓存更新策略
  6. 性能优化:缓存预热、压缩、异步处理
  7. 配置优化:灵活的缓存配置

通过合理使用这些缓存特性,可以显著提高应用性能和用户体验。

相关推荐
i学长的猫5 小时前
Ruby on Rails 从0 开始入门到进阶到高级 - 10分钟速通版
后端·ruby on rails·ruby
用户21411832636025 小时前
别再为 Claude 付费!Codex + 免费模型 + cc-switch,多场景 AI 编程全搞定
后端
茯苓gao5 小时前
Django网站开发记录(一)配置Mniconda,Python虚拟环境,配置Django
后端·python·django
Cherry Zack5 小时前
Django视图进阶:快捷函数、装饰器与请求响应
后端·python·django
程序媛徐师姐5 小时前
Java基于SpringBoot的茶叶商城系统,附源码+文档说明
java·spring boot·java springboot·茶叶商城系统·java茶叶商城系统·茶叶·java茶叶商城
爱读源码的大都督6 小时前
为什么有了HTTP,还需要gPRC?
java·后端·架构
码事漫谈6 小时前
致软件新手的第一个项目指南:阶段、文档与破局之道
后端
间彧6 小时前
Spring Boot条件注解详解与项目实战
后端
im_AMBER6 小时前
Web 开发 27
前端·javascript·笔记·后端·学习·web