有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何在Spring Boot中调用函数后释放所有缓存数据

我使用的是SpringBoot2.0.4。仅使用默认缓存提供程序启用缓存的发布版本未使用外部缓存提供程序

我已经安排了每天在特定时间运行的批处理。在其运行期间,涉及数据访问的某些方法调用被缓存,并且工作正常

现在,我想在下次按计划时间启动函数之前释放所有缓存项

我无法实现此功能。你们能给我一些想法或方法来实施它吗

这就是我试图实现的。我有一个标记为@Configuration的JobExecutionListener类。我正在用它的售后服务方法清除所有的缓存

@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();
        }
    }
}

共 (3) 个答案

  1. # 1 楼答案

    填充/清除缓存是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();
        }
    }
    

    这样,在下一个计划时间执行作业时,缓存将被清除

    您还可以创建一个tasklet步骤来清除缓存,并将其添加为作业的最后一步

    还有一个类似的问题,我在这里添加它作为参考:Spring Batch With Annotation and Caching

  2. # 2 楼答案

    可以使用@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注释

  3. # 3 楼答案

    在再次调用批处理之前,只需执行以下操作

    session.evict(Object)
    

    它将清除与该对象关联的所有以前的缓存

    你也可以做一个会话。清除()以完全驱逐它