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

时间:2018-09-28 09:38:55

标签: java spring-boot spring-batch spring-cache

我使用的是Spring Boot 2.0.4.RELEASE版本,并且仅使用默认缓存提供程序启用了缓存。

我已经计划了一批每天在特定时间运行的批次。在其运行期间,会缓存涉及数据访问的某些方法调用,并且该方法可以正常工作。

现在,我想在计划的下一次功能启动之前释放所有缓存的项目。

我无法实现此功能。你们都可以指导我一些想法或方法来实现它。

这就是我要实现的。我有一个标记为@Configuration的JobExecutionListener类。我正在使用其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();
        }
    }
}

3 个答案:

答案 0 :(得分: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注释。

答案 1 :(得分:0)

在再次调用您的批处理之前,只需执行

session.evict(Object)

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

您也可以执行session.clear()将其完全撤出

答案 2 :(得分:0)

填充/清除缓存是 public void installapk(String fileName) { File directory = getExternalFilesDir(null); File file = new File(directory,fileName); Intent intent = new Intent(Intent.ACTION_VIEW); Uri fileUri = FileProvider.getUriForFile(this, getApplicationContext().getPackageName() +".provider", file); intent.setDataAndType(fileUri, "application/vnd.android.package-archive"); intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent); } 的典型用例。在您的情况下,您可以创建一个自定义侦听器并使用JobExecutionListener方法清除缓存,例如:

afterJob

这样,在下一个预定时间执行作业时,缓存将被清除。

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

有一个与此类似的问题,我在这里添加以供参考:Spring Batch With Annotation and Caching