全部学科
Python全栈
python
NodeJS全栈
nodejs
小程序首页
📅 2026-05-18 10 分钟 ✍️ juanwangdev

Spring Boot缓存策略@Cacheable使用

Spring Cache 提供声明式缓存抽象,简化缓存实现。

开启缓存

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

缓存配置

YAML
spring:
  cache:
    type: redis
    redis:
      time-to-live: 3600000  # 1小时
      cache-null-values: false
      key-prefix: "app:"
      use-key-prefix: true

@Cacheable注解

查询时先查缓存,命中则返回,未命中则执行方法并缓存结果。

Java
@Service
public class UserService {

    @Cacheable(value = "users", key = "#id")
    public User getUserById(Long id) {
        log.info("查询数据库: {}", id);
        return userRepository.findById(id).orElse(null);
    }

    // 条件缓存
    @Cacheable(value = "users", key = "#id", unless = "#result == null")
    public User getUserByIdNotNull(Long id) {
        return userRepository.findById(id).orElse(null);
    }

    // SpEL表达式
    @Cacheable(value = "users", key = "#user.id + ':' + #user.type")
    public User getComplexKey(User user) {
        return userRepository.findById(user.getId()).orElse(null);
    }
}

@CachePut注解

每次都执行方法,并更新缓存。

Java
@Service
public class UserService {

    @CachePut(value = "users", key = "#user.id")
    public User updateUser(User user) {
        return userRepository.save(user);
    }

    @CachePut(value = "users", key = "#result.id")
    public User createUser(User user) {
        return userRepository.save(user);
    }
}

@CacheEvict注解

删除缓存条目。

Java
@Service
public class UserService {

    // 删除单个缓存
    @CacheEvict(value = "users", key = "#id")
    public void deleteUser(Long id) {
        userRepository.deleteById(id);
    }

    // 删除所有缓存
    @CacheEvict(value = "users", allEntries = true)
    public void clearAllUsers() {
        // 清空users缓存
    }

    // 方法执行前删除
    @CacheEvict(value = "users", key = "#id", beforeInvocation = true)
    public void deleteUserBefore(Long id) {
        // 即使方法异常也会删除缓存
    }
}

@Caching组合注解

Java
@Service
public class OrderService {

    @Caching(
        put = @CachePut(value = "orders", key = "#order.id"),
        evict = @CacheEvict(value = "userOrders", key = "#order.userId")
    )
    public Order createOrder(Order order) {
        return orderRepository.save(order);
    }
}

自定义KeyGenerator

Java
@Component
public class CustomKeyGenerator implements KeyGenerator {

    @Override
    public Object generate(Object target, Method method, Object... params) {
        StringBuilder sb = new StringBuilder();
        sb.append(target.getClass().getSimpleName()).append(":");
        sb.append(method.getName()).append(":");
        for (Object param : params) {
            sb.append(param.toString()).append(",");
        }
        return sb.toString();
    }
}

// 使用自定义KeyGenerator
@Cacheable(value = "users", keyGenerator = "customKeyGenerator")
public User getUser(String name, Integer age) {
    return userRepository.findByNameAndAge(name, age);
}

缓存注解对比

注解作用执行时机
@Cacheable查询缓存方法执行前检查
@CachePut更新缓存方法执行后更新
@CacheEvict删除缓存方法执行后删除

注意事项

@Cacheable不支持内部调用,需通过代理对象调用才能生效。

Java
@Service
public class UserService {

    @Cacheable(value = "users", key = "#id")
    public User getUser(Long id) {
        return userRepository.findById(id).orElse(null);
    }

    // 错误:内部调用缓存不生效
    public User getUserWrong(Long id) {
        return getUser(id);  // 直接调用,缓存失效
    }

    // 正确:通过代理对象调用
    @Autowired
    private UserService self;

    public User getUserRight(Long id) {
        return self.getUser(id);  // 代理调用,缓存生效
    }
}

要点总结

  • @Cacheable适合读多写少场景
  • @CachePut用于数据更新后刷新缓存
  • @CacheEvict用于数据删除时清理缓存
  • 注意内部调用和序列化问题

📝 发现内容有误?点击此处直接编辑

← 上一篇 Spring Boot监控指标体系
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库