SpringBoot中整合Redis

本文详细介绍如何在SpringBoot项目中整合Redis缓存,包括安装配置、代码实现及项目实战,提升系统运行速度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

更多Java架构师核心资料持续更新中https://github.com/kepeihong/data.git,内推阿里请查看链接

实际 开发 缓存 处理是必须的,不可能我们每次客户端去请求一次 服务器 ,服务器每次都要去 数据库 中进行查找,为什么要使用缓存?说到底是为了提高系统的运行速度。将用户频繁访问的内容存放在离用户最近,访问速度最 快的 地方,提高用户的响 应速度,今天先来讲下在 springboot 中整合 redis 的详细步骤。

一、 安装

首先要在本地安装一个redis程序,redis 下载 地址,安装过程十分简单(略过),安装完成后进入到redis文件夹中可以看到如下:

SpringBoot中整合Redis(缓存篇)

点击redis-server.exe开启redis服务,可以看到如下图所示即代表开启redis服务成功:

SpringBoot中整合Redis(缓存篇)

那么我们可以开启redis客户端进行 测试

SpringBoot中整合Redis(缓存篇)

二、整合到 spring boot

1、在项目中加入redis依赖, pom 文件中添加如下:

<!-- 整合Redis缓存支持 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

2、在appli cat ion.yml中添加redis 配置

##默认密码为空
redis:
      host: 127.0.0.1
      # Redis服务器连接端口
      port: 6379
      jedis:
        pool:
          #连接池最大连接数(使用负值表示没有限制)
          max-active: 100
          # 连接池中的最小空闲连接
          max-idle: 10
          # 连接池最大阻塞等待时间(使用负值表示没有限制)
          max-wait: 100000
      # 连接超时时间(毫秒)
      timeout: 5000
      #默认是索引为0的数据库
      database: 0

3、新建RedisConfiguration配置类,继承CachingConfigurerSupport,@EnableCaching开启注解

@Configuration
@EnableCaching
public class RedisConfiguration extends CachingConfigurerSupport {
    /**
     * 自定义生成key的规则
     */
    @Override
    public KeyGenerator keyGenerator() {
        return new KeyGenerator() {
            @Override
            public Object generate(Object o, Method method, Object... objects) {
                //格式化缓存key字符串
                StringBuilder sb = new StringBuilder();
                //追加类名
                sb.append(o.getClass().getName());
                //追加方法名
                sb.append(method.getName());
                //遍历参数并且追加
                for (Object obj : objects) {
                    sb.append(obj.toString());
                }
                System.out.println("调用Redis缓存Key : " + sb.toString());
                return sb.toString();
            }
        };
    }
    
    /**
     * 采用RedisCacheManager作为缓存管理器
     * @param connectionFactory
     */
    @Bean
    public CacheManager cacheManager(RedisConnectionFactory connectionFactory) {
        RedisCacheManager redisCacheManager = RedisCacheManager.create(connectionFactory);
        return  redisCacheManager;
    }

    @Bean
    public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {
        ////解决键、值序列化问题
        StringRedisTemplate template = new StringRedisTemplate(factory);
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        template.setValueSerializer(jackson2JsonRedisSerializer);
        template.afterPropertiesSet();
        return template;
    }
}

4、创建自定义的接口来定义需要的redis的功能

/**
 * K 指以hash结构操作时 键类型
 * T 为数据实体 应实现序列化接口,并定义serialVersionUID * RedisTemplate 提供了五种数据结构操作类型 hash / list / set / zset / value
 * 方法命名格式为 数据操作类型 + 操作 如 hashPut 指以hash结构(也就是map)想key添加键值对 
 */
public interface RedisHelper<HK, T> {
    /**
     * Hash结构 添加元素 * @param key key * @param hashKey hashKey * @param domain 元素
     */
    void hashPut(String key, HK hashKey, T domain);

    /**
     * Hash结构 获取指定key所有键值对 * @param key * @return
     */
    Map<HK, T> hashFindAll(String key);

    /**
     * Hash结构 获取单个元素 * @param key * @param hashKey * @return
     */
    T hashGet(String key, HK hashKey);

    void hashRemove(String key, HK hashKey);

    /**
     * List结构 向尾部(Right)添加元素 * @param key * @param domain * @return
     */
    Long listPush(String key, T domain);

    /**
     * List结构 向头部(Left)添加元素 * @param key * @param domain * @return
     */
    Long listUnshift(String key, T domain);

    /**
     * List结构 获取所有元素 * @param key * @return
     */
    List<T> listFindAll(String key);

    /**
     * List结构 移除并获取数组第一个元素 * @param key * @return
     */
    T listLPop(String key);

    /**
     * 对象的实体类
     * @param key
     * @param domain
     * @return
     */
    void valuePut(String key, T domain);

    /**
     * 获取对象实体类
     * @param key
     * @return
     */
    T getValue(String key);

    void remove(String key);

    /**
     * 设置过期时间 * @param key 键 * @param timeout 时间 * @param timeUnit 时间单位
     */
    boolean expirse(String key, long timeout, TimeUnit timeUnit);
}

下面是创建RedisHelperImpl进行接口的实现

@Service("RedisHelper")
public class RedisHelperImpl<HK, T> implements RedisHelper<HK, T> {
    // 在构造器中获取redisTemplate实例, key(not hashKey) 默认使用String类型
    private RedisTemplate<String, T> redisTemplate;
    // 在构造器中通过redisTemplate的工厂方法实例化操作对象
    private HashOperations<String, HK, T> hashOperations;
    private ListOperations<String, T> listOperations;
    private ZSetOperations<String, T> zSetOperations;
    private SetOperations<String, T> setOperations;
    private ValueOperations<String, T> valueOperations;

    // IDEA虽然报错,但是依然可以注入成功, 实例化操作对象后就可以直接调用方法操作Redis数据库
    @Autowired
    public RedisHelperImpl(RedisTemplate<String, T> redisTemplate) {
        this.redisTemplate = redisTemplate;
        this.hashOperations = redisTemplate.opsForHash();
        this.listOperations = redisTemplate.opsForList();
        this.zSetOperations = redisTemplate.opsForZSet();
        this.setOperations = redisTemplate.opsForSet();
        this.valueOperations = redisTemplate.opsForValue();
    }

    @Override
    public void hashPut(String key, HK hashKey, T domain) {
        hashOperations.put(key, hashKey, domain);
    }

    @Override
    public Map<HK, T> hashFindAll(String key) {
        return hashOperations.entries(key);
    }

    @Override
    public T hashGet(String key, HK hashKey) {
        return hashOperations.get(key, hashKey);
    }

    @Override
    public void hashRemove(String key, HK hashKey) {
        hashOperations.delete(key, hashKey);
    }

    @Override
    public Long listPush(String key, T domain) {
        return listOperations.rightPush(key, domain);
    }

    @Override
    public Long listUnshift(String key, T domain) {
        return listOperations.leftPush(key, domain);
    }

    @Override
    public List<T> listFindAll(String key) {
        if (!redisTemplate.hasKey(key)) {
            return null;
        }
        return listOperations.range(key, 0, listOperations.size(key));
    }

    @Override
    public T listLPop(String key) {
        return listOperations.leftPop(key);
    }

    @Override
    public void valuePut(String key, T domain) {
        valueOperations.set(key, domain);
    }

    @Override
    public T getValue(String key) {
        return valueOperations.get(key);
    }

    @Override
    public void remove(String key) {
        redisTemplate.delete(key);
    }

    @Override
    public boolean expirse(String key, long timeout, TimeUnit timeUnit) {
        return redisTemplate.expire(key, timeout, timeUnit);
    }
}

三、测试

编写TestRedis类进行测试

@RunWith(SpringRunner.class)
@SpringBootTest
public class TestRedis {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private RedisHelperImpl redisHelper;

    @Test
    public void test() throws Exception{
//        基本写法
//        stringRedisTemplate.opsForValue().set("aaa","111");
//        Assert.assertEquals("111",stringRedisTemplate.opsForValue().get("aaa"));
//        System.out.println(stringRedisTemplate.opsForValue().get("aaa"));
        Author user=new Author();
        user.setName("Alex");
        user.setIntro_l("不会打篮球的程序不是好男人");
        redisHelper.valuePut("aaa",user);
        System.out.println(redisHelper.getValue("aaa"));
    }

    @Test
    public void testObj() throws Exception {
        Author user=new Author();
        user.setName("Jerry");
        user.setIntro_l("不会打篮球的程序不是好男人!");

        ValueOperations<String, Author> operations=redisTemplate.opsForValue();
        operations.set("502", user);
        Thread.sleep(500);
        boolean exists=redisTemplate.hasKey("502");
        if(exists){
            System.out.println(redisTemplate.opsForValue().get("502"));
        }else{
            System.out.println("exists is false");
        }
        // Assert.assertEquals("aa", operations.get("com.neo.f").getUserName());
    }
}

运行TestRedis测试类,结果如下:

SpringBoot中整合Redis(缓存篇)

注意:如果在RedisConfiguration中不配置redisTemplate(RedisConnectionFactory factory)注解,会造成键、值的一个序列化问题,有兴趣的可以去试一下。

四、项目实战

上面的redis相关写法是我们自定义设置并获取的,那么我们经常要在访问接口的地方去使用redis进行缓存相关实体对象以及集合等,那么我们怎么实现呢?比如我现在想在AuthorController中去缓存作者相关信息的缓存数据,该怎么办呢?如下:

@RestController
@RequestMapping(value = "/poem")
public class AuthorController {

    private final static Logger logger = LoggerFactory.getLogger(AuthorController.class);

    @Autowired
    private AuthorRepository authorRepository;

    @Cacheable(value="poemInfo")  //自动根据方法生成缓存
    @PostMapping(value = "/poemInfo")
    public Result<Author> author(@RequestParam("author_id") int author_id, @RequestParam("author_name")String author_name) {
        if(StringUtils.isEmpty(author_id) || StringUtils.isEmpty(author_name)){
            return ResultUtils.error(ResultCode.INVALID_PARAM_EMPTY);
        }
        Author author;
        Optional<Author> optional = authorRepository.getAuthorByIdAndName(author_id, author_name);
        if (optional.isPresent()) {
            author = optional.get();
            //通过/n或者多个空格 进行过滤去重
            if (!StringUtils.isEmpty(author.getIntro_l())) {
                String s = author.getIntro_l();
                String intro = s.split("//s +")[0];
                author.setIntro_l(intro);
            }
        } else {
           return ResultUtils.error(ResultCode.NO_FIND_THINGS);
        }
        return ResultUtils.ok(author);
    }
}

这里 @Cacheable(value="poemInfo")这个注解的意思就是自动根据方法生成缓存,value就是缓存下来的key。

<think>好的,我现在需要帮助用户解决在Spring Boot 3.0中整合Redis的问题。首先,我应该回想一下Spring Boot 3.0的新特性和与Redis整合的基本步骤。记得Spring Boot 3.0需要Java 17或更高版本,这可能是一个前提条件,用户需要确认他们的环境是否符合要求。 接下来,整合Redis通常需要添加相关的依赖。在Spring Boot 2.x中,常用的依赖是spring-boot-starter-data-redis,但到了3.0,可能依赖的版本号有所变化。需要检查最新的Spring Data Redis文档,确保使用正确的依赖配置。例如,可能需要使用Spring Boot 3.0对应的Spring Data 2022.0.0或更高版本。 然后,配置Redis连接信息。用户需要在application.properties或application.yml文件中设置Redis服务器的主机地址、端口、密码等信息。这里可能会涉及到是否使用lettuce作为默认的连接池,因为Spring Boot从2.x开始默认使用Lettuce而不是Jedis,这一点在3.0中可能继续保持。 接下来是创建配置类,可能涉及到RedisTemplate和StringRedisTemplate的配置。需要确保这些Bean被正确创建,并且序列化方式设置正确,避免出现序列化问题。通常会建议使用Jackson2JsonRedisSerializer来替代默认的JdkSerializationRedisSerializer,以便更友好地处理JSON数据。 然后,用户可能需要编写Repository或者使用RedisTemplate直接操作数据。这里需要给出示例代码,比如如何保存、获取、删除键值对,或者如何使用Hash操作。同时,要提醒用户注意事务管理和管道操作的使用,如果有相关需求的话。 另外,异常处理也是需要考虑的部分。比如连接失败时的处理,或者Redis服务器不可用时的回退机制。可能需要提到Spring的异常处理机制,或者使用@Cacheable等注解时的缓存异常处理。 还有可能涉及到高级功能,比如发布/订阅模式、分布式锁的实现,或者与Spring Cache集成,使用@Cacheable注解来简化缓存逻辑。需要根据用户的具体需求来决定是否展开这些内容。 测试部分也很重要,建议用户编写测试用例,使用@SpringBootTest来验证Redis配置是否正确,数据操作是否如预期。可能需要使用嵌入式Redis服务器进行测试,但注意Spring Boot 3.0是否支持常见的嵌入式Redis库,或者是否需要使用测试容器(Testcontainers)。 最后,需要生成相关问题,可能包括性能优化、集群配置、SSL连接、与其他数据库的整合等,以帮助用户进一步探索。 现在需要确保所有步骤都符合Spring Boot 3.0的最新要求,比如Jakarta EE的包名变更(javax到jakarta),这可能影响到某些配置类或依赖项。同时,检查是否有过时的API或注解,确保示例代码的准确性和兼容性。 可能还需要参考官方文档或可靠的教程,确保提供的信息是最新和正确的。例如,Spring Data Redis的官方文档或Spring Boot的指南,确保依赖项版本和配置示例正确无误。 总结一下,步骤大致是:环境准备、添加依赖、配置连接信息、配置RedisTemplate、编写数据操作代码、异常处理、测试,以及可能的进阶功能。每个步骤都需要详细说明,并给出代码示例,同时注意3.0版本的新变化。</think>在Spring Boot 3.0中整合Redis可通过以下步骤实现,注意新版本对JDK 17和Jakarta EE 9的依赖升级[^1]: ### 步骤1:添加依赖 ```xml <!-- pom.xml --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>io.lettuce</groupId> <artifactId>lettuce-core</artifactId> </dependency> ``` ### 步骤2:配置连接参数 ```properties # application.properties spring.data.redis.host=localhost spring.data.redis.port=6379 spring.data.redis.password=yourpassword spring.data.redis.lettuce.pool.max-active=8 ``` ### 步骤3:配置序列化规则 ```java @Configuration public class RedisConfig { @Bean public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) { RedisTemplate<String, Object> template = new RedisTemplate<>(); template.setConnectionFactory(factory); template.setKeySerializer(new StringRedisSerializer()); template.setValueSerializer(new GenericJackson2JsonRedisSerializer()); return template; } } ``` ### 步骤4:操作示例 ```java @Service public class UserService { @Autowired private RedisTemplate<String, Object> redisTemplate; public void saveUser(User user) { redisTemplate.opsForValue().set("user:" + user.getId(), user); } public User getUser(String userId) { return (User) redisTemplate.opsForValue().get("user:" + userId); } } ``` ### 高级整合:缓存注解 ```java @SpringBootApplication @EnableCaching public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } @Service public class ProductService { @Cacheable(value = "products", key = "#id") public Product getProductById(String id) { // 数据库查询逻辑 } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ke&chen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值