在 Spring 框架中,可通过多种方式配置缓存具体行为,常见配置方法如下。
1. 缓存管理器(CacheManager)配置
基于内存的缓存管理器配置(以SimpleCacheManager为例)
SimpleCacheManager 是 Spring 提供的简单缓存管理器,用于管理内存缓存。适用于开发和测试阶段,或数据量小、缓存一致性要求不高的场景。
首先需要在Spring配置文件(如applicationContext.xml
)或者通过Java配置类(使用@Configuration
注解)来配置SimpleCacheManager
。
下面代码定义了一个CacheManager
类型的bean
。通过SimpleCacheManager
创建了一个缓存管理器,并设置了两个基于ConcurrentMapCache
的缓存,名称分别为userCache
和productCache
。这些缓存名称可以在@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 配置类配置JedisConnectionFactory
和RedisCacheManager
。
下面配置首先创建了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)表达式来动态生成缓存键。
在查询用户信息的方法中,以用户id
和lastName
为缓存键。代码中,key
属性表达式#user.id + '-' + #user.lastName
将用户对象的id
和lastName
拼接成字符串作缓存键。如此,即便有多个用户对象,只要id
和lastName
组合不同,就会存于不同缓存位置。
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();
}
}