Как работает Spring Cache и какие реализации вы использовали
Что проверяют
Понимаете ли вы, что Spring Cache это абстракция поверх прокси, а не сам кэш, и можете ли объяснить, почему аннотация иногда молча не срабатывает. Вторая часть про ваш опыт: следом спросят, как вы выбирали TTL и как держали кэш согласованным между инстансами.
Как отвечать
Механика: @EnableCaching включает AOP-прокси вокруг бинов. При вызове метода с @Cacheable прокси вычисляет ключ, спрашивает CacheManager и либо отдаёт значение, либо вызывает метод и сохраняет результат. Отсюда главное ограничение: вызов изнутри того же класса идёт мимо прокси, и кэш не работает.
Аннотации:
@Cacheable: читает из кэша, при промахе выполняет метод. Ключ по умолчанию собирается из всех аргументов, свой задаётся SpEL (key = "#id"), естьconditionиunless, аsync = trueне даёт нескольким потокам одного инстанса считать одно значение одновременно;@CachePut: метод выполняется всегда, результат записывается в кэш;@CacheEvict: удаляет запись или весь кэш черезallEntries = true.
Реализации:
- без провайдера: Spring Boot поднимает
ConcurrentMapCacheManager, без TTL и без лимита размера. Годится для тестов; - Caffeine: локальный кэш в памяти, настройка вида
spring.cache.caffeine.spec=maximumSize=10000,expireAfterWrite=10m, вытеснение по алгоритму W-TinyLFU; - Redis: общий кэш для всех инстансов, TTL через
spring.cache.redis.time-to-live, значения лучше хранить в JSON, а не в Java-сериализации; - JCache: так подключают Ehcache 3 и Hazelcast. Поддержку Ehcache 2 из Spring 6 убрали.
Про опыт говорите конкретно: что кэшировали, какой TTL поставили и почему, какой был процент попаданий. Если работали только с Caffeine, так и скажите и объясните, когда перешли бы на Redis.
Где спотыкаются
Не знают про самовызов и удивляются, что @Cacheable не срабатывает при вызове из соседнего метода того же бина.
Оставляют кэш по умолчанию в проде. Без TTL и лимита он растёт до OutOfMemoryError.
Держат локальный кэш на нескольких инстансах и сбрасывают его @CacheEvict только там, где прошло изменение. Остальные отдают устаревшие данные до истечения TTL или перезапуска.