Spring Batch With Annotation and Caching

纵饮孤独 提交于 2019-12-18 09:36:24

问题


Does anyone have good example of Spring Batch (Using Annotation) to cache a reference table which will be accessible to processor ?

I just need a simple cache, run a query which returns some byte[] and keep it in memory till the time job is executing.

Appreciate any help on this topic.

Thanks !


回答1:


A JobExecutionListener can be used to populate the cache with reference data before the job is executed and clear the cache after the job is finished.

Here is an example:

import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobExecutionListener;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.CacheManager;
import org.springframework.cache.concurrent.ConcurrentMapCacheManager;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@EnableBatchProcessing
public class MyJob {

    @Autowired
    private JobBuilderFactory jobs;

    @Autowired
    private StepBuilderFactory steps;

    @Bean
    public CacheManager cacheManager() {
        return new ConcurrentMapCacheManager(); // return the implementation you want
    }

    @Bean
    public Tasklet tasklet() {
        return new MyTasklet(cacheManager());
    }

    @Bean
    public Step step() {
        return steps.get("step")
                .tasklet(tasklet())
                .build();
    }

    @Bean
    public JobExecutionListener jobExecutionListener() {
        return new CachingJobExecutionListener(cacheManager());
    }

    @Bean
    public Job job() {
        return jobs.get("job")
                .start(step())
                .listener(jobExecutionListener())
                .build();
    }

    class MyTasklet implements Tasklet {

        private CacheManager cacheManager;

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

        @Override
        public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
            String name = (String) cacheManager.getCache("referenceData").get("foo").get();
            System.out.println("Hello " + name);
            return RepeatStatus.FINISHED;
        }
    }

    class CachingJobExecutionListener implements JobExecutionListener {

        private CacheManager cacheManager;

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

        @Override
        public void beforeJob(JobExecution jobExecution) {
            // populate cache as needed. Can use a jdbcTemplate to query the db here and populate the cache
            cacheManager.getCache("referenceData").put("foo", "bar");
        }

        @Override
        public void afterJob(JobExecution jobExecution) {
            // clear cache when the job is finished
            cacheManager.getCache("referenceData").clear();
        }
    }

    public static void main(String[] args) throws Exception {
        ApplicationContext context = new AnnotationConfigApplicationContext(MyJob.class);
        JobLauncher jobLauncher = context.getBean(JobLauncher.class);
        Job job = context.getBean(Job.class);
        jobLauncher.run(job, new JobParameters());
    }

}

When executed, it prints:

Hello bar

which means data is correctly retrieved from the cache. You would need to adapt the sample to query the database and populate the cache (See comments in code).

Hope this helps.




回答2:


You can use ehcache-jsr107 implementation. Very quick to setup. Spring and ehcache integration example is available here. You should be able to setup same with spring batch also.

Hope this hleps



来源:https://stackoverflow.com/questions/52642796/spring-batch-with-annotation-and-caching

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!