Spring 框架:配置缓存管理器、注解参数与过期时间

在 Spring 框架中,可通过多种方式配置缓存具体行为,常见配置方法如下。

1. 缓存管理器(CacheManager)配置

基于内存的缓存管理器配置(以SimpleCacheManager为例)

SimpleCacheManager 是 Spring 提供的简单缓存管理器,用于管理内存缓存。适用于开发和测试阶段,或数据量小、缓存一致性要求不高的场景。

首先需要在Spring配置文件(如applicationContext.xml)或者通过Java配置类(使用@Configuration注解)来配置SimpleCacheManager

下面代码定义了一个CacheManager类型的bean。通过SimpleCacheManager创建了一个缓存管理器,并设置了两个基于ConcurrentMapCache的缓存,名称分别为userCacheproductCache。这些缓存名称可以在@Cacheable@CachePut@CacheEvict等注解的cacheNames属性中使用。

java 复制代码
  import org.springframework.cache.CacheManager;
  import org.springframework.cache.annotation.EnableCaching;
  import org.springframework.cache.concurrent.ConcurrentMapCache;
  import org.springframework.cache.support.SimpleCacheManager;
  import org.springframework.context.annotation.Bean;
  import org.springframework.context.annotation.Configuration;
  import java.util.Arrays;

  @Configuration
  @EnableCaching
  public class CacheConfig {
      @Bean
      public CacheManager cacheManager() {
          SimpleCacheManager cacheManager = new SimpleCacheManager();
          cacheManager.setCaches(Arrays.asList(
              new ConcurrentMapCache("userCache"),
              new ConcurrentMapCache("productCache")
          ));
          return cacheManager;
      }
  }

基于Redis的缓存管理器配置(以JedisConnectionFactory和RedisCacheManager为例)

Redis是一个高性能的分布式缓存数据库,在生产环境中被广泛使用。通过配置Redis缓存管理器,可以将Spring应用的缓存数据存储到Redis中,实现数据的共享和高效访问。

添加 Redis 依赖如spring-boot-starter-data-redis(Spring Boot 项目)。再用 Java 配置类配置JedisConnectionFactoryRedisCacheManager

下面配置首先创建了JedisConnectionFactory,用于建立与Redis服务器的连接。可以在其中设置Redis服务器的主机名、端口等信息。然后创建了RedisTemplate,用于在Redis中进行数据的读写操作,同时设置了键和值的序列化方式。最后通过RedisCacheManager创建了缓存管理器,它将使用之前配置的RedisConnectionFactory来管理缓存数据与Redis的交互。

java 复制代码
  import org.springframework.cache.CacheManager;
  import org.springframework.cache.annotation.EnableCaching;
  import org.springframework.context.annotation.Bean;
  import org.springframework.context.annotation.Configuration;
  import org.springframework.data.redis.cache.RedisCacheManager;
  import org.springframework.data.redis.connection.RedisConnectionFactory;
  import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
  import org.springframework.data.redis.core.RedisTemplate;
  import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
  import org.springframework.data.redis.serializer.StringRedisSerializer;

  @Configuration
  @EnableCaching
  public class RedisCacheConfig {
      @Bean
      public RedisConnectionFactory redisConnectionFactory() {
          JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory();
          // 可以配置Redis服务器的主机名、端口等信息
          jedisConnectionFactory.setHostName("localhost");
          jedisConnectionFactory.setPort(6379);
          return jedisConnectionFactory;
      }

      @Bean
      public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
          RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
          redisTemplate.setConnectionFactory(redisConnectionFactory);
          redisTemplate.setKeySerializer(new StringRedisSerializer());
          redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
          return redisTemplate;
      }

      @Bean
      public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
          RedisCacheManager cacheManager = RedisCacheManager.create(redisConnectionFactory);
          return cacheManager;
      }
  }

2. 缓存注解参数配置

自定义缓存键(Key)

通过自定义缓存键,可以更精确地控制缓存数据的存储和检索。合理的缓存键设计可以避免缓存数据的冲突,提高缓存的命中率。

@Cacheable@CachePut@CacheEvict等注解中使用key属性来指定缓存键。可以使用SpEL(Spring Expression Language)表达式来动态生成缓存键。

在查询用户信息的方法中,以用户idlastName为缓存键。代码中,key属性表达式#user.id + '-' + #user.lastName将用户对象的idlastName拼接成字符串作缓存键。如此,即便有多个用户对象,只要idlastName组合不同,就会存于不同缓存位置。

java 复制代码
  @Cacheable(cacheNames = "userCache", key = "#user.id + '-' + #user.lastName")
  public User getUser(User user) {
      // 从数据库查询用户信息的逻辑
      return userRepository.findByUser(user);
  }

缓存条件(Condition)配置

缓存条件配置允许根据特定的条件来决定是否进行缓存操作。这在一些复杂的业务场景中非常有用,例如只缓存满足一定条件的数据,或者根据业务规则来决定是否更新或清除缓存。

使用@Cacheable@CachePut@CacheEvict注解的condition属性,通过SpEL表达式来指定条件。

例如只缓存年龄大于 18 岁的用户信息,年龄大于 18 岁时查询结果才被缓存。若用户年龄小于等于 18 岁,每次调用方法执行数据库查询,不使用缓存。

java 复制代码
  @Cacheable(cacheNames = "userCache", condition = "#user.age > 18")
  public User getUser(User user) {
      // 从数据库查询用户信息的逻辑
      return userRepository.findByUser(user);
  }

3. 缓存过期时间配置

基于特定缓存实现的过期时间设置

不同的缓存实现技术(如Ehcache、Redis等)有自己的过期时间设置方式。对于基于内存的缓存,过期时间设置可能相对简单;而对于分布式缓存,可能需要考虑更多的因素,如数据一致性等。

在Redis中,可以通过在存储缓存数据时设置过期时间来实现。在Spring应用中,当使用RedisCacheManager时,RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofMinutes(30))设置了默认的缓存过期时间为30分钟。所有存储到Redis中的缓存数据,如果没有单独设置过期时间,将在30分钟后自动过期。

java 复制代码
  import org.springframework.cache.CacheManager;
  import org.springframework.cache.annotation.EnableCaching;
  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;

  @Configuration
  @EnableCaching
  public class RedisCacheExpirationConfig {
      @Bean
      public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
          RedisCacheConfiguration defaultCacheConfig = RedisCacheConfiguration.defaultCacheConfig()
             .entryTtl(Duration.ofMinutes(30))
             .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
             .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));

          return RedisCacheManager.builder(redisConnectionFactory)
             .cacheDefaults(defaultCacheConfig)
             .build();
      }
  }
相关推荐
NightDW2 分钟前
连续周更任务模块的设计与实现
java·后端·mysql
华仔啊3 分钟前
什么情况下用线程池,怎么用?看完就会
java·后端
灵魂猎手7 分钟前
8. Mybatis插件体系
java·后端·源码
SimonKing7 分钟前
布隆过滤器:用微小的空间代价换取高效的“可能存在”判定
java·后端·程序员
阿冲Runner8 分钟前
Lombok的@Builder与Mybatis-Plus配合使用踩坑
java·后端·mybatis
菜鸟的迷茫10 分钟前
Java 锁机制对比:Synchronized、ReentrantLock、StampedLock
java·后端
花花无缺13 分钟前
java的异常-Exception、Error
java·后端
架构师沉默13 分钟前
架构师的秘密武器:Java SPI 插件机制解密
java·后端·架构
xiaohezi15 分钟前
搞懂 ThreadLocal,其实就三件事:它是谁?它在哪?用完它咋办?
java
whitepure16 分钟前
万字详解Java多线程(一)
java·后端