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. 配置优化:灵活的缓存配置

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

相关推荐
uzong20 分钟前
软件架构指南 Software Architecture Guide
后端
又是忙碌的一天20 分钟前
SpringBoot 创建及登录、拦截器
java·spring boot·后端
勇哥java实战分享1 小时前
短信平台 Pro 版本 ,比开源版本更强大
后端
学历真的很重要1 小时前
LangChain V1.0 Context Engineering(上下文工程)详细指南
人工智能·后端·学习·语言模型·面试·职场和发展·langchain
计算机毕设VX:Fegn08951 小时前
计算机毕业设计|基于springboot + vue二手家电管理系统(源码+数据库+文档)
vue.js·spring boot·后端·课程设计
上进小菜猪2 小时前
基于 YOLOv8 的智能杂草检测识别实战 [目标检测完整源码]
后端
冰冰菜的扣jio2 小时前
Redis缓存中三大问题——穿透、击穿、雪崩
java·redis·缓存
韩师傅3 小时前
前端开发消亡史:AI也无法掩盖没有设计创造力的真相
前端·人工智能·后端
栈与堆3 小时前
LeetCode-1-两数之和
java·数据结构·后端·python·算法·leetcode·rust
oMcLin3 小时前
如何在 AlmaLinux 9 上配置并优化 Redis 集群,支持高并发的实时数据缓存与快速查询?
数据库·redis·缓存