卡飞资源网

专业编程技术资源共享平台

Spring Boot3 整合 Redis,这些缓存注解你真的会用吗?

你在开发 Spring Boot3 项目时,有没有遇到过这样的困扰?随着项目功能不断增加,数据量逐渐庞大,接口响应速度变得越来越慢,用户体验直线下降。好不容易找到优化方向 —— 引入 Redis 缓存,可在实际使用 Spring Boot3 与 Redis 整合的缓存注解时,却发现状况百出:缓存数据不生效、缓存更新不及时,甚至出现数据不一致的情况…… 别着急,这篇文章就是来帮你解决这些问题的!

开启缓存功能的第一步:@EnableCaching 注解

在使用缓存注解前,有一个关键步骤千万不能忘,那就是在 Spring Boot3 项目的主应用类或者配置类上加上@EnableCaching注解。这就好比打开缓存世界的大门,只有加上这个注解,后续的缓存注解才能生效。

例如,在你的 Spring Boot3 项目主类Application.java中,只需要添加一行代码:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;

@SpringBootApplication
@EnableCaching
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

这样,Spring Boot3 项目就开启了缓存功能,为后续使用缓存注解做好了准备。

核心缓存注解详解

@Cacheable:查询场景的好帮手

@Cacheable注解用于标记一个方法的结果应该被缓存。当该方法被调用时,Spring 会先检查缓存中是否已经存在对应的结果,如果存在,就直接从缓存中返回数据,不再执行方法体,这样能大大减少数据库查询等耗时操作。

比如在一个用户管理模块中,我们有一个查询用户信息的方法:

import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

@Service
public class UserService {

    @Cacheable(value = "user", key = "#p0.id")
    public User getUserById(User user) {
        // 这里原本可能是从数据库查询用户信息的逻辑
        // 假设通过复杂的SQL查询从数据库获取用户
        return userRepository.findById(user.getId()).orElse(null);
    }
}

这里的value指定了缓存的名称为 “user”,key = "#p0.id"则表示以方法第一个参数user的id属性作为缓存的键。也就是说,当你第一次调用getUserById方法查询某个用户信息时,结果会被存入 “user” 缓存中,之后再查询相同用户信息,就可以直接从缓存获取,无需再次执行从数据库查询的方法。

@CachePut:数据更新的守护者

@CachePut注解与@Cacheable有所不同。@CachePut是在方法执行后将返回值放入缓存,它不管缓存中是否已经存在数据,都会执行方法,然后将执行结果更新到缓存中。

这在数据更新场景非常有用,比如用户修改了个人信息。我们可以在更新用户信息的方法上加上@CachePut注解:

import org.springframework.cache.annotation.CachePut;
import org.springframework.stereotype.Service;

@Service
public class UserService {

    @CachePut(value = "user", key = "#p0.id")
    public User updateUser(User user) {
        // 这里是更新用户信息到数据库的逻辑
        User updatedUser = userRepository.save(user);
        return updatedUser;
    }
}

这样每次修改用户信息后,缓存中的用户信息也会随之更新,保证了缓存数据与数据库数据的一致性。

@CacheEvict:缓存清理大师

@CacheEvict注解主要用于在数据修改或删除时,移除缓存中的旧数据。当你删除某个用户信息时,为了避免后续查询还从缓存中获取到已经删除的数据,就可以在删除方法上添加@CacheEvict注解:

import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Service;

@Service
public class UserService {

    @CacheEvict(value = "user", key = "#p0.id")
    public void deleteUser(User user) {
        userRepository.delete(user);
    }
}

这样就能精准地清除缓存中对应的数据;如果你想清空整个 “user” 缓存空间的数据,使用@CacheEvict(value = "user", allEntries = true)即可:

import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Service;

@Service
public class UserService {

    @CacheEvict(value = "user", allEntries = true)
    public void clearUserCache() {
        // 这里可以添加一些清理缓存前的业务逻辑
    }
}

缓存注解使用进阶技巧

除了掌握这些基本的缓存注解使用方法,在实际开发中,还有一些小技巧能让你更好地使用缓存注解。

合理设置缓存过期时间

为了避免缓存数据长期不更新导致数据陈旧,我们可以为缓存设置过期时间。在@Cacheable、@CachePut等注解中,可以通过cacheManager结合配置类来设置。

例如,在配置类中定义一个缓存管理器,并设置缓存的过期时间:

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 java.time.Duration;

@Configuration
@EnableCaching
public class CacheConfig {

    @Bean
    public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
        RedisCacheConfiguration cacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
               .entryTtl(Duration.ofMinutes(5)) // 设置缓存过期时间为5分钟
               .disableCachingNullValues()
               .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));

        return RedisCacheManager.builder(redisConnectionFactory)
               .cacheDefaults(cacheConfiguration)
               .build();
    }
}

应对缓存穿透、缓存雪崩等问题

缓存穿透是指查询一个一定不存在的数据,由于缓存不命中,每次都要去数据库查询,给数据库带来巨大压力。可以通过布隆过滤器等方式来过滤掉非法请求。

缓存雪崩是指大量缓存集中在同一时间失效,导致大量请求直接访问数据库。可以通过设置不同的缓存过期时间,避免缓存集体失效;也可以使用 Redis 的哨兵模式、集群模式来提高系统的可用性和稳定性。

总结

通过对 Spring Boot3 整合 Redis 的缓存注解的学习,相信你已经对如何优化项目性能有了更清晰的思路。从开启缓存功能的@EnableCaching注解,到核心的@Cacheable、@CachePut、@CacheEvict注解,再到使用缓存注解的进阶技巧,每一个环节都至关重要。

现在,不妨回到你的项目中,按照这些方法实践起来!如果你在使用过程中遇到了其他问题,或者有更好的经验和技巧,欢迎在评论区留言分享,大家一起交流学习,共同打造高性能的 Spring Boot3 项目!

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言