Spring Cache 提供了一种简单的方法来通过注解对方法的返回结果进行缓存。结合 Redis,可以构建一个高效的分布式缓存解决方案。
以下是详细实现步骤:
1. 引入必要的依赖
在 pom.xml
文件中添加以下依赖(适用于 Spring Boot 项目):
<dependencies>
<!-- Spring Boot Starter for Cache -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<!-- Spring Boot Starter for Redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- Optional: Redis client for Lettuce -->
<dependency>
<groupId>io.lettuce.core</groupId>
<artifactId>lettuce-core</artifactId>
</dependency>
</dependencies>
2. 配置 Redis
在 application.yml
或 application.properties
文件中配置 Redis 连接信息:
spring:
cache:
type: redis
redis:
host: localhost
port: 6379
# Optional: Redis password
# password: yourpassword
3. 启用缓存功能
在主启动类上添加 @EnableCaching
注解:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
@SpringBootApplication
@EnableCaching
public class CacheApplication {
public static void main(String[] args) {
SpringApplication.run(CacheApplication.class, args);
}
}
4. 实现缓存功能
1. 使用缓存注解
在需要缓存的方法上使用 Spring 提供的注解:@Cacheable
: 在调用方法时检查缓存,如果有缓存则返回缓存数据;如果没有,则执行方法并将结果存入缓存。@CachePut
: 不管是否存在缓存,每次都会执行方法,并将结果更新到缓存。@CacheEvict
: 用于移除缓存。@Caching
: 组合多个缓存操作。
示例代码:
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.stereotype.Service;
@Service
public class UserService {
// 查询用户信息,结果将存入缓存
@Cacheable(value = "users", key = "#id")
public String getUserById(Long id) {
System.out.println("Fetching user from database...");
return "User" + id; // 模拟从数据库获取用户
}
// 更新用户信息,并同步更新缓存
@CachePut(value = "users", key = "#id")
public String updateUser(Long id, String name) {
System.out.println("Updating user in database...");
return name; // 模拟更新后的用户数据
}
// 删除用户信息,同时清除缓存
@CacheEvict(value = "users", key = "#id")
public void deleteUser(Long id) {
System.out.println("Deleting user from database...");
}
}
2. 复杂缓存逻辑
如果需要组合操作,可以使用 @Caching
注解:
import org.springframework.cache.annotation.Caching;
@Caching(
put = { @CachePut(value = "users", key = "#user.id") },
evict = { @CacheEvict(value = "users", key = "'allUsers'") }
)
public User saveUser(User user) {
// Save user to database
return user;
}
5. 配置缓存序列化
为了提高 Redis 存储的效率,可以使用 JSON 或其他格式进行序列化。以下是示例配置:
1. 创建 Redis 配置类
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
// 设置 key 序列化器
template.setKeySerializer(new StringRedisSerializer());
// 设置 value 序列化器
template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
template.setHashKeySerializer(new StringRedisSerializer());
template.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
template.afterPropertiesSet();
return template;
}
}
2. 验证序列化
使用上述配置后,Redis 存储的数据将以 JSON 格式显示,更加直观且易于调试。
6. 运行和测试
示例调用:
UserService userService = new UserService();
// 第一次调用会执行方法
System.out.println(userService.getUserById(1L));
// 第二次调用会从缓存中获取
System.out.println(userService.getUserById(1L));
// 更新用户并更新缓存
userService.updateUser(1L, "NewName");
// 删除用户并清除缓存
userService.deleteUser(1L);
运行后,可以观察到数据库查询方法不会重复执行,数据从缓存中获取,同时缓存的更新和删除操作都能正常运行。
总结
通过 Spring Cache 和 Redis,可以快速实现基于注解的缓存功能,适用于大多数简单缓存场景。如果你有更复杂的需求,可以在 Spring Cache 的基础上自定义实现策略或扩展功能!
发布者:myrgd,转载请注明出处:https://www.object-c.cn/4989