Как освободить все кешированные данные после вызова функции в Spring Boot

Я использую версию Spring Boot 2.0.4.RELEASE с включенным кешем и только с поставщиком кеша по умолчанию. Внешний поставщик кеша не используется.

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

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

Я не могу реализовать эту функцию. Можете ли вы подсказать мне несколько идей или способов их реализации.

Это то, что я пытаюсь реализовать. У меня есть класс JobExecutionListener, помеченный как @Configuration. Я использую его метод afterJob для очистки всех кешей.

@Configuration
@JobScope
public class JobTwoExecutionListener implements JobExecutionListener {

    private static final Logger logger = LoggerFactory.getLogger(JobTwoExecutionListener.class);

    @Autowired
    private CacheManager cacheManager;

    @Override
    public void beforeJob(JobExecution jobExecution) {
        final String methodName = "beforeJob() : ";
        logger.info(methodName + "called");

        if(cacheManager == null) return;

        logger.info(methodName + "CacheManager FOUND. Listing all the caches 
        before Job Run");
        for(String name : cacheManager.getCacheNames()){
            logger.info(methodName + "CACHE_NAME BEFORE JOB " + name);
        }
    }

    @Override
    public void afterJob(JobExecution jobExecution) {
        final String methodName = "afterJob() : ";
        logger.info(methodName + "called");

        performCacheCleanup();
    }

    private void performCacheCleanup(){
        final String methodName = "performCacheCleanup() : ";
        logger.info(methodName + "called");

        if(cacheManager == null){
            logger.info(methodName + "CacheManager NOT FOUND");
            return;
        }

        logger.info(methodName + "CacheManager FOUND. Listing & clearing all the caches after Job Run");

        for(String name : cacheManager.getCacheNames()){
            if(name == null) continue;

            logger.info(methodName + "CLEARING CACHE " + name + " AFTER JOB");
            Cache cache = cacheManager.getCache(name);
            if(cache != null) cache.clear();
        }
    }
}

person Nitish Kumar    schedule 28.09.2018    source источник
comment
вы реализовали кеш eh2?   -  person Vikram Saini    schedule 28.09.2018
comment
Нет только кеширование по умолчанию. Внешний поставщик кеша не используется   -  person Nitish Kumar    schedule 28.09.2018
comment
Думаю, именно здесь вы бы использовали @ CacheEvict. Обязательно подумайте о том, чтобы не хранить кеш все время, пока пакет не запущен (если пакет не предназначен для вычислений для кеша, и в противном случае не должно быть никакого вытеснения кеша).   -  person M. Prokhorov    schedule 28.09.2018


Ответы (3)


Вы можете аннотировать конкретный метод для вызова, используя @CacheEvict

@CacheEvict(value = "cachename", allEntries=true)       
public void doSomethingBeforeEvict(Object object) {
    //do something, cache evicted after this method
}

Или введите кеш-менеджер и удалите все кеши

@Service
public class ServiceCacheManagerExample {

    @Autowired 
    private CacheManager cacheManager;     

    public void clearAllCaches(){
        for(String name:cacheManager.getCacheNames()){
            cacheManager.getCache(name).clear();    
        }
    }
}

обновленный ответ на основе вопроса об обновлении

Вы используете неправильную аннотацию @Configuration в слушателе вакансий.

person ValerioMC    schedule 29.09.2018
comment
Spring не вводит CacheManager с аннотацией @Autowired в класс конфигурации - person Nitish Kumar; 04.10.2018
comment
@Configuration вы можете определить только @Bean или передать объект @Bean, это зависит от того, как вы хотите его использовать, но я не думаю, что это подходящее место. Если вы не хотите использовать @CacheEvict, вы можете определить @Component или @Service для его внедрения, чтобы вы могли явно очистить кеш, когда вам нужно. с помощью метода обслуживания emptyCache(s), например - person ValerioMC; 04.10.2018
comment
Я не думаю, что это так. У меня есть классы с аннотациями Configuration, в которых я использовал Autowired для внедрения DataSource и EntityManager. Другое дело, почему не внедряется CacheManager! - person Nitish Kumar; 06.10.2018
comment
Почему вы хотите внедрить CacheManager внутри @Configuration класса? Выселить объект? Это не то место. Если вы хотите инициализировать, вам нужно определить CacheManager как @Bean, тогда вы можете ввести в свой уровень сервиса - person ValerioMC; 06.10.2018
comment
Нет необходимости определять CacheManager как @Bean. Весна уже сделала это. ! Я использую класс JobExecutionListener для очистки всего кеша в методе afterJob (). Я пометил JobExecutionListener как Configuration. В некоторых других сервисах я также могу использовать Autowired CacheManager! - person Nitish Kumar; 06.10.2018
comment
Добавлен код Реализации в исходный пост. Пожалуйста, посмотрите @valeriomc - person Nitish Kumar; 06.10.2018
comment
Не пробовал это решение. Но спасибо за реализацию. Пробовал решение Махмуда, и оно сработало. - person Nitish Kumar; 08.10.2018
comment
Я думаю, что, вероятно, вам следует понять аннотации «@Bean», «@Configuration» и «@Component» для лучшего смысла и использования. - person ValerioMC; 08.10.2018

Заполнение / очистка кеша - типичный случай использования JobExecutionListener. В вашем случае вы можете создать собственный слушатель и очистить кеш в методе afterJob, например:

@Component
class MyJobExecutionListener extends JobExecutionListenerSupport {

    private CacheManager cacheManager;

    public MyJobExecutionListener(CacheManager cacheManager) {
        this.cacheManager = cacheManager;
    }

    @Override
    public void afterJob(JobExecution jobExecution) {
        cacheManager.getCache("mycache").clear();
    }
}

Таким образом, кеш будет очищен, когда ваше задание будет выполнено в следующий запланированный раз.

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

Есть вопрос, похожий на этот, я добавляю его сюда для справки: Spring Batch С аннотациями и кешированием.

person Mahmoud Ben Hassine    schedule 30.09.2018
comment
Работал как шарм! Спасибо. Есть ли разница между JobExecutionListenerSupport и JobExecutionListener, кроме того, что одно является абстрактным, а другое - реализацией? - person Nitish Kumar; 08.10.2018
comment
Рад, что помог. JobExecutionListenerSupport - это бесполезная реализация JobExecutionListener. Это вспомогательный класс, который можно использовать для переопределения только тех методов, которые вам интересны, и не нужно реализовывать все методы. Таким образом, вы можете использовать один из них, результат тот же. В качестве примечания, похоже, вы отредактировали вопрос, добавив пример слушателя после того, как я ответил на вопрос. Пожалуйста, четко отметьте свои правки в вопросе, иначе мой ответ покажется каким-то глупым, так как он дает то же решение, что и в вопросе. - person Mahmoud Ben Hassine; 08.10.2018

прежде чем снова позвонить в свою партию, просто сделайте

session.evict(Object)

Он очистит весь предыдущий кеш, связанный с этим объектом.

вы также можете сделать session.clear (), чтобы полностью исключить его

person Vikram Saini    schedule 28.09.2018
comment
Какую сессию вы здесь упоминаете? И как провести эту сессию? - person Nitish Kumar; 28.09.2018
comment
ваш сеанс с базой данных, и вам нужно его автоматически подключить, но перед этим его необходимо зарегистрировать в контейнере spring, и я надеюсь, что вы уже это сделали - person Vikram Saini; 08.10.2018