Руководство по кэшированию весной

Руководство по кэшированию весной

1. Абстракция кеша?

В этой статье мы собираемся показать, какuse the Caching Abstraction in Spring - и в целом повысить производительность вашей системы.

Мы включим простое кеширование для некоторых примеров реальных методов и обсудим, как мы можем практически улучшить производительность этих вызовов с помощью интеллектуального управления кешем.

Дальнейшее чтение:

Пример Spring Boot Ehcache

Краткое и практическое руководство по использованию Spring с Ehcache.

Read more

Выселение кэша в Spring Boot

Узнайте, как сделать недействительными кэши с помощью Spring Boot.

Read more

2. Начиная

Базовая абстракция кеширования, предоставляемая Spring, находится в модулеspring-context . Итак, при использовании Maven нашpom.xml должен содержать следующую зависимость:


    org.springframework
    spring-context
    5.1.8.RELEASE

Интересно, что есть еще один модуль с именемspring-context-support,, который находится поверх смодуляspring-context и предоставляет еще несколькоCacheManagers , поддерживаемых подобнымиEhCache илиCaffeine. Если вы собираетесь использовать их в качестве хранилища кеша, используйте вместо них Smodulespring-context-support :


    org.springframework
    spring-context-support
    5.1.8.RELEASE

Поскольку модульspring-context-support транзитивно зависит от смодуляspring-context , нет необходимости в отдельном объявлении зависимости дляspring-context.

2.1. Весенний ботинок

Если вы пользователь Spring Boot, используйте пакетspring-boot-starter-cache starter, чтобы легко добавить зависимости кеширования:


    org.springframework.boot
    spring-boot-starter-cache

Под капотом стартер заводит дымкуspring-context-support .

3. Включить кеширование

Чтобы включить кэширование, Spring хорошо использует аннотации, так же, как и включение любой другой функции уровня конфигурации в платформе.

Функцию кэширования можно декларативно включить, просто добавив аннотацию@EnableCaching к любому из классов конфигурации:

@Configuration
@EnableCaching
public class CachingConfig {

    @Bean
    public CacheManager cacheManager() {
        return new ConcurrentMapCacheManager("addresses");
    }
}

Вы, конечно, также можете настроитьenable cache management with XML:


    

    
        
            
                
            
        
    

Note: После включения кеширования - для минимальной настройки - мыmust регистрируемcacheManager.

Using XML does enable more flexible options для настройки кэширования - вы можете указать свой собственный Cache-Manager, Cache-Resolver, Error-Handler и, как правило, использовать более расширенные параметры настройки (refer to the Javadoc для более подробной информации).

3.1. Весенний ботинок

При использовании Spring Boot простое присутствие стартового пакета в пути к классам вместе с саннотациейEnableCaching регистрирует тот же самыйConcurrentMapCacheManager. So, поэтому нет необходимости в отдельном объявлении bean-компонента.

Кроме того, мы можем настроитьauto-configuredCacheManager , подозревая один или несколькоCacheManagerCustomizer<T> beans:

@Component
public class SimpleCacheCustomizer
  implements CacheManagerCustomizer {

    @Override
    public void customize(ConcurrentMapCacheManager cacheManager) {
        cacheManager.setCacheNames(asList("users", "transactions"));
    }
}

СаутоконфигурацияCacheAutoConfiguration берет эти средства настройки и применяет их к текущемуCacheManager  перед своей полной инициализацией.

4. Использование кеширования с аннотациями

После того как вы включили кэширование, следующий шаг - привязать поведение кэширования к методам с декларативными аннотациями.

4.1. @Cacheable

Самый простой способ включить кэширование для метода - разграничить его с помощью@Cacheable и параметризовать его именем кеша, в котором будут храниться результаты:

@Cacheable("addresses")
public String getAddress(Customer customer) {...}

ВызовgetAddress() сначала проверяет кешaddresses перед фактическим вызовом метода, а затем кеширует результат.

Хотя в большинстве случаев достаточно одного кэша, среда Spring также поддерживает несколько кэшей для передачи в качестве параметров:

@Cacheable({"addresses", "directory"})
public String getAddress(Customer customer) {...}

____ В этом случае, если какой-либо из кэшей содержит требуемый результат, результат возвращается, и метод не вызывается.

4.2. @CacheEvict __

Теперь, в чем будет проблема с созданием всех методов@Cacheable?

Проблема в размере -we don’t want to populate the cache with values that we don’t need often. Кэши могут расти довольно большими, довольно быстрыми, и мы могли бы хранить много устаревших или неиспользуемых данных.

Аннотация@CacheEvict используется для указания удаления одного или нескольких / всех значений, чтобы новые значения можно было снова загрузить в кеш:

@CacheEvict(value="addresses", allEntries=true)
public String getAddress(Customer customer) {...}

Здесь мы используем дополнительный параметрallEntries вместе с очищаемым кешем, чтобы очистить все записи в кэшеaddresses и подготовить его для новых данных.

__ 4.3. @CachePut

Хотя@CacheEvict сокращает накладные расходы на поиск записей в большом кэше, удаляя устаревшие и неиспользуемые записи, в идеале вы хотите использоватьavoid evicting too much data out of the cache.

Вместо этого вам нужно выборочно и разумно обновлять записи всякий раз, когда они меняются.

С помощью аннотации@CachePut вы можете обновлять содержимое кеша, не мешая выполнению метода. То есть метод всегда выполняется, а результат кэшируется.

@CachePut(value="addresses")
public String getAddress(Customer customer) {...}

Разница между@Cacheable и@CachePut заключается в том, что@Cacheable будетskip running the method, тогда как@CachePut будетactually run the method, а затем поместит свои результаты в кеш.

4.4. @Caching

Что делать, если вы хотите использовать несколько аннотаций одного типа для кэширования метода. Посмотрите на неправильный пример ниже:

@CacheEvict("addresses")
@CacheEvict(value="directory", key=customer.name)
public String getAddress(Customer customer) {...}

Приведенный выше код не сможет скомпилироваться, поскольку Java не позволяет объявлять несколько аннотаций одного типа для данного метода.

Обходной путь к вышеупомянутому вопросу будет:

@Caching(evict = {
  @CacheEvict("addresses"),
  @CacheEvict(value="directory", key="#customer.name") })
public String getAddress(Customer customer) {...}

Как показано во фрагменте кода выше, вы можетеgroup multiple caching annotations с@Caching и использовать его для реализации собственной настраиваемой логики кэширования.

4.5. @CacheConfig

С аннотацией@CacheConfig вы можетеstreamline some of the cache configuration into a single place – at the class level - чтобы вам не приходилось объявлять что-то несколько раз:

@CacheConfig(cacheNames={"addresses"})
public class CustomerDataService {

    @Cacheable
    public String getAddress(Customer customer) {...}

5. Условное кеширование

Иногда кэширование может не сработать для метода во всех ситуациях.

Например - повторное использование нашего примера из аннотации@CachePut - это будет выполнять как метод, так и кешировать результаты каждый раз:

@CachePut(value="addresses")
public String getAddress(Customer customer) {...}

5.1. Параметр состояния

Теперь - если нам нужен больший контроль над активностью аннотации -@CachePut можно параметризовать с помощью параметра условия, который принимает выражение SpEL, чтобы гарантировать, что результаты кэшируются на основе оценки этого выражения:

@CachePut(value="addresses", condition="#customer.name=='Tom'")
public String getAddress(Customer customer) {...}

5.2. Если параметр

Мы также можем управлять кешированиемbased on the output of the method rather than the input - через параметрunless:

@CachePut(value="addresses", unless="#result.length()<64")
public String getAddress(Customer customer) {...}

Приведенная выше аннотация будет кэшировать адреса, если они не короче 64 символов.

Важно знать, что параметрыcondition иunless можно использовать вместе со всеми аннотациями кеширования.

Этот вид условного кэширования может оказаться весьма полезным для управления большими результатами и настройки поведения на основе входных параметров вместо применения общего поведения для всех операций.

6. Декларативное кэширование на основе XML

Если у вас нет доступа к исходному коду приложения или вы хотите внедрить поведение кэширования извне, вы также можете использовать декларативное кэширование на основе XML.

Вот наша конфигурация XML:





    
        
            
            
        
    



    
        
    



Related