← Назад к вопросам
Какая аннотация используется для работы с кэшем?
1.2 Junior🔥 141 комментариев
#Кэширование и NoSQL
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
# Аннотации для работы с кэшем в Spring
Spring предоставляет мощные аннотации для управления кэшированием. Это позволяет улучшить производительность приложения, сокращая время обработки часто используемых данных.
1. @Cacheable (Чтение из кэша)
Основная аннотация для кэширования результатов методов:
@Service
public class UserService {
@Cacheable("users") // Кэшировать результат в кэше "users"
public User getUserById(Long id) {
// Если это вызов повторно с одним и тем же id,
// результат вернётся из кэша, метод не выполнится
System.out.println("Загружаю пользователя из БД: " + id);
return userRepository.findById(id).orElse(null);
}
// С условием кэширования
@Cacheable(value = "users", condition = "#id > 100")
public User getCachedIfBigId(Long id) {
return userRepository.findById(id).orElse(null);
}
// С unless (инверсия condition)
@Cacheable(value = "users", unless = "#result == null")
public User getUserOrNull(Long id) {
return userRepository.findById(id).orElse(null);
}
// С кастомным ключом кэша
@Cacheable(value = "users", key = "'user_' + #id")
public User getUser(Long id) {
return userRepository.findById(id).orElse(null);
}
}
Параметры:
value/cacheNames— имя кэшаkey— ключ для сохранения (SpEL выражение)condition— условие кэшированияunless— когда НЕ кэшировать
2. @CachePut (Обновление кэша)
Всегда выполняет метод и обновляет кэш:
@Service
public class UserService {
@CachePut("users") // Выполнить метод И обновить кэш
public User updateUser(User user) {
System.out.println("Обновляю пользователя в БД");
return userRepository.save(user);
}
// С условием и ключом
@CachePut(value = "users", key = "#result.id")
public User createUser(String name, String email) {
return userRepository.save(new User(name, email));
}
}
Отличие от @Cacheable:
@Cacheable— возвращает из кэша если есть@CachePut— всегда выполняет и обновляет
3. @CacheEvict (Очистка кэша)
Удаляет данные из кэша:
@Service
public class UserService {
@CacheEvict("users") // Удалить из кэша
public void deleteUser(Long id) {
System.out.println("Удаляю пользователя");
userRepository.deleteById(id);
}
// Удалить все из кэша
@CacheEvict(value = "users", allEntries = true)
public void clearAllUsers() {
System.out.println("Очищаю весь кэш пользователей");
}
// Удалить с условием
@CacheEvict(value = "users", condition = "#id > 1000")
public void deleteIfBigId(Long id) {
userRepository.deleteById(id);
}
}
4. @Caching (Комбинированные операции)
Для сложных сценариев с несколькими операциями кэша:
@Service
public class UserService {
@Caching(
put = {
@CachePut(value = "users", key = "#result.id"),
@CachePut(value = "usersByEmail", key = "#result.email")
}
)
public User createUser(String name, String email) {
return userRepository.save(new User(name, email));
}
@Caching(
evict = {
@CacheEvict(value = "users", key = "#id"),
@CacheEvict(value = "usersByEmail", allEntries = true)
}
)
public void deleteUser(Long id) {
userRepository.deleteById(id);
}
}
5. @CacheConfig (Конфигурация на уровне класса)
Задаёт дефолтный кэш для всего класса:
@Service
@CacheConfig(cacheNames = "users") // Дефолтный кэш для всех методов
public class UserService {
@Cacheable // Используется "users" кэш из @CacheConfig
public User getUserById(Long id) {
return userRepository.findById(id).orElse(null);
}
@CacheEvict(allEntries = true) // Очищает "users" кэш
public void refreshAll() {
}
}
Конфигурация кэша
Способ 1: Простое включение
@Configuration
@EnableCaching // Включить поддержку кэша
public class CacheConfig {
}
В application.properties:
spring.cache.type=simple
Способ 2: Redis кэш (Production)
@Configuration
@EnableCaching
public class CacheConfig {
@Bean
public LettuceConnectionFactory connectionFactory() {
return new LettuceConnectionFactory();
}
}
Добавить зависимость:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
Конфигурация:
spring.cache.type=redis
spring.redis.host=localhost
spring.redis.port=6379
Способ 3: Caffeine кэш (In-memory)
@Configuration
@EnableCaching
public class CacheConfig {
@Bean
public CacheManager cacheManager() {
return new CaffeineCacheManager("users", "posts", "comments");
}
}
Или с настройками:
@Bean
public CacheManager cacheManager() {
CaffeineCacheManager manager = new CaffeineCacheManager("users");
manager.setCaffeine(Caffeine.newBuilder()
.maximumSize(1000)
.expireAfterWrite(10, TimeUnit.MINUTES));
return manager;
}
Практический пример
@Service
public class UserService {
private final UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
// Получить с кэшем
@Cacheable(value = "users", key = "#id")
public User findById(Long id) {
System.out.println("Запрос к БД для id: " + id);
return userRepository.findById(id).orElse(null);
}
// Получить все (без кэша — сложно для больших объёмов)
public List<User> findAll() {
return userRepository.findAll();
}
// Создать и добавить в кэш
@CachePut(value = "users", key = "#result.id")
public User create(String name, String email) {
System.out.println("Создание нового пользователя");
return userRepository.save(new User(name, email));
}
// Обновить
@CachePut(value = "users", key = "#user.id")
public User update(User user) {
System.out.println("Обновление пользователя: " + user.getId());
return userRepository.save(user);
}
// Удалить
@CacheEvict(value = "users", key = "#id")
public void delete(Long id) {
System.out.println("Удаление пользователя: " + id);
userRepository.deleteById(id);
}
}
Пример использования:
UserService service = new UserService(repo);
// Первый вызов — идёт в БД
User user1 = service.findById(1L); // "Запрос к БД для id: 1"
// Второй вызов — из кэша
User user2 = service.findById(1L); // Ничего не выводится (из кэша)
// Обновление
user1.setName("New Name");
service.update(user1); // Кэш обновлен
// Удаление
service.delete(1L); // Кэш очищен для id=1
Ключевые моменты
| Аннотация | Действие | Когда использовать |
|---|---|---|
| @Cacheable | Вернуть из кэша если есть | Чтение данных |
| @CachePut | Всегда выполнить и обновить кэш | Обновление, создание |
| @CacheEvict | Удалить из кэша | Удаление, инвалидация |
| @Caching | Комбинировать операции | Сложные сценарии |
| @CacheConfig | Дефолтная конфигурация | Упрощение аннотаций |
Best Practices
- Кэшируйте read-only методы — чаще всего @Cacheable
- Тщательно выбирайте ключи кэша — могут быть конфликты
- Инвалидируйте кэш при изменениях — @CacheEvict
- Используйте условия — не кэшируйте всё подряд
- Redis для микросервисов — общий кэш между сервисами
- Caffeine для монолитов — in-memory кэш, быстро
- Мониторьте попадания в кэш — не кэшируйте впустую