使用 Redis 和 Spring Cache 实现基于注解的缓存功能

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.ymlapplication.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

Like (0)
Previous 2024年12月1日 下午1:00
Next 2024年12月1日 下午1:40

相关推荐

  • 远程仓库 ,从GitHub拉取代码失败的解决办法

    从GitHub拉取代码失败通常由以下几种原因引起:网络问题、认证失败、远程仓库配置错误等。以下是常见的失败场景及解决办法。 1. 网络问题症状连接超时。报错如:fatal: unable to access ‘https://github.com/…’: Failed to connect to github.com port 443: Connecti…

    2024年11月28日
    00
  • 通过 PHP 读取微软邮箱(Outlook/Office 365 邮箱)

    通过 PHP 读取微软邮箱(Outlook/Office 365 邮箱)邮件,通常需要使用 Microsoft Graph API,因为微软逐步淘汰了基于用户名和密码的 IMAP/SMTP 方式。Microsoft Graph API 支持 OAuth2.0 认证,可以安全地访问和管理用户邮件。 以下是实现读取微软邮箱邮件的完整示例。 实现步骤 1. 准备工…

    2024年11月25日
    00
  • C++ STL vector 类:动态数组的高效应用

    vector 是 C++ 标准库(STL)中最常用的容器之一,它提供了一个动态数组的实现,能够根据需要自动扩展或收缩。vector 是一个线性数据结构,具有高效的随机访问能力和动态扩展能力,广泛应用于需要频繁增删元素且对随机访问要求较高的场景。 1. vector 类简介 vector 是 C++ 标准模板库(STL)中提供的一种容器类,它类似于动态数组(d…

    2024年11月25日
    00
  • 最新 pragma solidity 0 . 5 . 10 报错原因解决

    pragma solidity 0.5.10 会报错的原因通常与当前使用的 Solidity 编译器版本不支持该指定版本的语法有关。要解决此问题,需要确保使用正确的编译器版本或调整代码中的版本声明。 问题分析指定的版本过旧: Solidity 0.5.10 是较旧的版本,而现代的工具链(如 Truffle 或 Hardhat)可能默认安装更新版本的编译器。不…

    2024年11月27日
    00
  • Redis 一个高性能的内存数据存储系统

    Redis 缓存详解 Redis 是一个高性能的内存数据存储系统,广泛用于缓存和会话存储。它支持多种数据结构(如字符串、哈希、列表、集合、有序集合等),使其非常适合用于缓存策略的实现。下面将详细解释 Redis 缓存 中常见的问题和解决方案,涵盖性能优化、缓存失效、缓存穿透、缓存雪崩、缓存击穿等常见缓存问题。 1. 缓存穿透 缓存穿透 指的是查询的数据根本不…

    2024年11月23日
    00
  • java算法— 动态规划之斐波那契数列模型

    斐波那契数列是动态规划中一个经典的模型,其递推关系简单易懂,非常适合作为入门练习。斐波那契数列的定义如下: 在 Java 中,可以通过递归、带记忆化的递归、迭代和优化空间复杂度的方式实现斐波那契数列。 1. 递归实现 最直观的实现,但存在大量重复计算,时间复杂度为 O(2n)。 2. 带记忆化的递归 通过一个数组存储已计算的值,避免重复计算,时间复杂度降为 …

    2024年11月21日
    00
  • 在使用 Kettle 9.1 连接 MySQL 时,遇到错误提示 Connection failed. Verify all connection parameters and confirm that the appropriate driver is installed.

    在使用 Kettle 9.1 连接 MySQL 时,遇到错误提示 Connection failed. Verify all connection parameters and confirm that the appropriate driver is installed. 通常是由于以下几个原因导致的: 1. MySQL 驱动未正确配置Kettle 需要…

    2024年11月27日
    00
  • 在国内访问 GitHub 可能会遇到加载缓慢或无法打开的问题

    在国内访问 GitHub 可能会遇到加载缓慢或无法打开的问题,这通常与网络连接、DNS 设置或网络限制有关。以下是几种解决方法: 1. 更改 DNSDNS 配置错误可能导致 GitHub 无法正常访问。可以尝试修改 DNS 为公共 DNS 服务:推荐使用:阿里云 DNS:223.5.5.5 和 223.6.6.6Google DNS:8.8.8.8 和 8.…

    2024年11月27日
    00
  • 在 Apache Kafka 中消息的消费和传递通过消费者与 Kafka 的分布式系统协作完成

    在 Apache Kafka 中,消息的消费和传递是通过消费者(Consumer)与 Kafka 的分布式系统协作完成的。以下是消息传递的主要流程: 1. Producer 生产消息到 Kafka 2. Consumer 消费消息 Kafka 中消费者的消息消费流程如下: 2.1 订阅主题 消费者通过 Kafka 客户端订阅一个或多个主题。它可以: 2.2 …

    2024年12月9日
    00
  • 使用 Webpack 5 优化构建减少生成文件的体积提升前端性能

    在使用 Webpack 5 时,优化构建以减少生成文件的体积是提升前端性能的重要一步。以下是一些常见的优化方法和策略: 1. 开启生产模式 确保构建时使用生产模式,Webpack 会自动应用多种优化(如代码压缩、Tree Shaking 等): 或在配置文件中明确设置: 2. 启用 Tree Shaking Tree Shaking 是 Webpack 内置…

    2024年12月3日
    00
  • Oracle中RegExp_Like 正则表达式函数的基本用法

    在 Oracle 数据库中,REGEXP_LIKE 是一个用于匹配正则表达式的函数。它通常用于检查一个字符串是否符合某个正则表达式的模式。它是 Oracle 正则表达式功能的一部分,允许你在 SQL 查询中使用正则表达式进行数据验证或过滤。 语法 示例 1. 基本使用 检查字符串是否符合给定的正则表达式模式。 此查询将查找 column_name 中仅包含字…

    2024年11月23日
    00
  • 远程访问 VMware ESXi 主机的方法

    远程访问 VMware ESXi 主机可以通过以下几种方式实现。具体方法取决于你的网络环境和目标需求,例如是否有公网 IP,是否需要加密传输等。以下是详细教程: 1. 基于公网 IP 的直接访问 1.1 适用场景 1.2 操作步骤 2. 使用 VPN 隧道访问 2.1 适用场景 2.2 操作步骤 3. 配置跳板机访问 3.1 适用场景 3.2 操作步骤 远程…

    2024年11月24日
    00
  • 在 MySQL 中 ORDER BY和HAVING用于数据查询和处理

    在 MySQL 中,ORDER BY和HAVING是用于数据查询和处理的两个重要子句,通常与SELECT语句一起使用,以下是它们的具体使用方法: ORDER BY子句 其中,column1、column2等是要排序的列名。ASC表示升序排序(默认),DESC表示降序排序。 多列排序示例:如果要先按照部门编号升序排序,再按照工资降序排序,可以这样写: 按表达式…

    2024年12月15日
    00
  • 出现 ERROR 1045 (28000): Access denied for user ‘root’@’localhost’ (using password: YES) 错误的解决方法

    出现 ERROR 1045 (28000): Access denied for user ‘root’@’localhost’ (using password: YES) 错误,通常是由于 MySQL 用户身份验证失败,可能的原因包括密码错误、用户权限配置问题或身份验证插件不匹配等。以下是解决方法: 1. 检查密码是否正确确保输入的密码与 MySQL 中为…

    2024年11月26日
    00
  • 云服务器安装宝塔强制重启导致MySQL无法启动

    在云服务器上进行 强制重启 后,MySQL 无法启动的情况,通常是由于以下几种原因引起的。强制重启可能会导致 MySQL 数据库的文件系统损坏、配置文件丢失、锁定文件问题等,下面是一些排查和解决方法。1. 检查 MySQL 错误日志MySQL 无法启动时,首先需要查看 MySQL 的错误日志,以获取更多的错误信息。错误日志通常位于 /var/log/mysq…

    2024年11月29日
    00

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

联系我们

在线咨询: QQ交谈

邮件:723923060@qq.com

关注微信