使用步骤:
1.导入相关依赖(redis、Springcache)
<!-- Spring Boot Starter Cache --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-cache</artifactId> </dependency> <!-- Redis 缓存实现 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
2.配置缓存信息(application.yml)
spring: # redis配置 redis: # redis服务器地址 host: ${sky.redis.host} # redis服务器端口 port: ${sky.redis.port} # redis密码,没有可不写 password: ${sky.redis.password} # redis数据库索引(默认为0、默认库有0-15) database: ${sky.redis.database} # 缓存配置 cache: # 缓存类型 type: redis
3.添加Redis配置类(RedisConfig.java、这里是因为使用的redsis,所以配置合在一起了)
package com.sky.config; import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import lombok.extern.slf4j.Slf4j; import org.springframework.cache.CacheManager; import org.springframework.cache.annotation.EnableCaching; import org.springframework.cache.interceptor.KeyGenerator; 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.core.RedisTemplate; import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.RedisSerializationContext; import org.springframework.data.redis.serializer.RedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; import java.lang.reflect.Method; import java.time.Duration; import java.util.Random; /** * Redis配置类,用于配置RedisTemplate以支持自定义的序列化和反序列化。 * 通过自定义序列化器,可以将复杂的Java对象序列化为JSON格式存储到Redis中,并在读取时反序列化为Java对象。 */ @Configuration @EnableCaching @Slf4j public class RedisConfig { /** * 配置RedisTemplate以使用自定义序列化器。 * * @param redisConnectionFactory Redis连接工厂,用于创建Redis连接 * @return 配置好的RedisTemplate实例 */ @Bean public RedisTemplate<Object, Object> redisTemplate( RedisConnectionFactory redisConnectionFactory) { log.info("开始创建RedisTemplate实例..."); // 创建RedisTemplate实例 RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>(); // 设置Redis连接工厂 redisTemplate.setConnectionFactory(redisConnectionFactory); // 使用Jackson2JsonRedisSerializer替换默认的序列化方式,以便将对象序列化为JSON格式存储在Redis中 Jackson2JsonRedisSerializer jsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); // 配置ObjectMapper以解决查询缓存转换异常 ObjectMapper om = new ObjectMapper(); // 支持Java8的时间类型 om.registerModule(new JavaTimeModule()); om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); jsonRedisSerializer.setObjectMapper(om); // 设置RedisTemplate的value序列化器为自定义的JSON序列化器 // 这样可以将复杂的Java对象序列化为JSON格式存储到Redis中 redisTemplate.setValueSerializer(jsonRedisSerializer); // 设置RedisTemplate的key序列化器为StringRedisSerializer // 这样可以将字符串类型的键存储到Redis中 redisTemplate.setKeySerializer(new StringRedisSerializer()); // 初始化RedisTemplate,确保所有属性设置正确 redisTemplate.afterPropertiesSet(); // 返回配置好的RedisTemplate实例 return redisTemplate; } /** * 创建自定义的KeyGenerator,用于生成缓存的键。 * * @return 自定义的KeyGenerator实例 */ @Bean public KeyGenerator keyGenerator() { return new KeyGenerator() { @Override public Object generate(Object target, Method method, Object... params) { // 格式化缓存key字符串 StringBuilder sb = new StringBuilder(); // 追加类名 sb.append(target.getClass().getName()); // 追加方法名 sb.append(method.getName()); // 遍历参数并追加 for (Object obj : params) { sb.append(obj.toString()); } return sb.toString(); } }; } /** * 配置CacheManager以使用自定义的序列化和反序列化。 * * @param factory Redis连接工厂,用于创建Redis连接 * @return 配置好的CacheManager实例 */ @Bean public CacheManager cacheManager(RedisConnectionFactory factory) { // 创建Redis序列化对象 RedisSerializer<String> redisSerializer = new StringRedisSerializer(); // 创建Jackson的序列化对象 Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); // 解决查询缓存转换异常的问题 ObjectMapper om = new ObjectMapper(); // 支持Java8的时间类型 om.registerModule(new JavaTimeModule()); om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); jackson2JsonRedisSerializer.setObjectMapper(om); // 配置序列化(解决乱码的问题) RedisCacheConfiguration configuration = RedisCacheConfiguration.defaultCacheConfig() // 设置缓存过期时间 .entryTtl(Duration.ofSeconds(new Random().nextInt(+0*60*60*24+new Random().nextInt(+60*60*24)))) .serializeKeysWith(RedisSerializationContext.SerializationPair. fromSerializer(redisSerializer)) .serializeValuesWith(RedisSerializationContext.SerializationPair. fromSerializer(jackson2JsonRedisSerializer)) .disableCachingNullValues(); RedisCacheManager cacheManager = RedisCacheManager.builder(factory) .cacheDefaults(configuration).build(); return cacheManager; } }
4.开启Redis缓存支持、启动类添加注解(@EnableCaching)
//在启动类添加注解,开启缓存支持 @EnableCaching
常用注解:
@Cacheable
作用:
将方法的结果存储在缓存中,下次调用相同参数的方法时直接从缓存中获取结果,而不是重新执行方法。
常用属性:
value 或 cacheNames:指定缓存的名称。
key:指定缓存的键,可以使用 SpEL 表达式。
unless:指定条件,如果条件为真,则不缓存结果。
condition:指定条件,如果条件为真,则缓存结果。
示例:
import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; @Service public class UserService { @Cacheable(value = "users", key = "#id") public User getUserById(String id) { // 模拟从数据库中查询用户 return userRepository.findById(id); } }
@CachePut
作用:
更新缓存中的值,每次方法调用后都会将结果存入缓存。
常用属性:
value 或 cacheNames:指定缓存的名称。
key:指定缓存的键,可以使用 SpEL 表达式。
unless:指定条件,如果条件为真,则不缓存结果。
condition:指定条件,如果条件为真,则缓存结果。
示例:
import org.springframework.cache.annotation.CachePut; import org.springframework.stereotype.Service; @Service public class UserService { @CachePut(value = "users", key = "#user.id") public User updateUser(User user) { // 更新用户信息并返回 return userRepository.save(user); } }
@CacheEvict
作用:
从缓存中删除指定的条目。
常用属性:
value 或 cacheNames:指定缓存的名称。
key:指定缓存的键,可以使用 SpEL 表达式。
allEntries:如果为 true,则清除所有缓存条目。
beforeInvocation:如果为 true,则在方法调用前清除缓存;默认为 false,即在方法调用
清除缓存。
示例:
import org.springframework.cache.annotation.CacheEvict; import org.springframework.stereotype.Service; @Service public class UserService { @CacheEvict(value = "users", key = "#id") public void deleteUser(String id) { // 删除用户 userRepository.deleteById(id); } @CacheEvict(value = "users", allEntries = true) public void clearAllUsersCache() { // 清除所有用户的缓存 } }
@Caching
作用:
组合多个缓存操作,适用于复杂场景。
常用属性:
cacheable:包含 @Cacheable 注解的数组。
put:包含 @CachePut 注解的数组。
evict:包含 @CacheEvict 注解的数组。
示例:
import org.springframework.cache.annotation.Cacheable; import org.springframework.cache.annotation.CachePut; import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.Caching; import org.springframework.stereotype.Service; @Service public class UserService { @Caching( cacheable = { @Cacheable(value = "users", key = "#id") }, put = { @CachePut(value = "users", key = "#user.id") }, evict = { @CacheEvict(value = "users", key = "#oldId") } ) public User updateUser(String oldId, User user) { // 更新用户信息并返回 user.setId(oldId); return userRepository.save(user); } }
@CacheConfig
作用:
在类级别定义缓存配置,避免在每个方法上重复相同的缓存配置。
常用属性:
value 或 cacheNames:指定缓存的名称。
keyGenerator:指定自定义的键生成器。
cacheManager:指定自定义的缓存管理器。
cacheResolver:指定自定义的缓存解析器。
示例:
import org.springframework.cache.annotation.CacheConfig; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; @Service @CacheConfig(cacheNames = "users") public class UserService { @Cacheable(key = "#id") public User getUserById(String id) { // 模拟从数据库中查询用户 return userRepository.findById(id); } @CachePut(key = "#user.id") public User updateUser(User user) { // 更新用户信息并返回 return userRepository.save(user); } @CacheEvict(key = "#id") public void deleteUser(String id) { // 删除用户 userRepository.deleteById(id); } }