In this post, we will show you how to use Spring TaskScheduler to schedule a batch job to run every 10 seconds.
Project structure
This is a directory structure of the standard gradle project.
Project dependencies
task wrapper(type: Wrapper) { gradleVersion = '3.2.1' } apply plugin: 'java' apply plugin: 'eclipse' apply plugin: 'org.springframework.boot' sourceCompatibility = 1.8 repositories { mavenLocal() mavenCentral() } dependencies { compileOnly('org.projectlombok:lombok:1.16.12') compile('org.springframework.boot:spring-boot-starter-batch:1.5.2.RELEASE') testCompile('org.springframework.boot:spring-boot-starter-test:1.5.2.RELEASE') } buildscript { repositories { mavenLocal() jcenter() } dependencies { classpath "org.springframework.boot:spring-boot-gradle-plugin:1.5.2.RELEASE" } }
You can know more about cron from here.
application.properties file
#cron cron.job.expression=*/10 * * * * *
Spring TaskScheduler
The TaskScheduler
will schedule the below job.
package com.walking.techie.taskscheduler.scheduler; import org.springframework.batch.core.Job; import org.springframework.batch.core.JobExecution; import org.springframework.batch.core.JobParameters; import org.springframework.batch.core.JobParametersBuilder; import org.springframework.batch.core.JobParametersInvalidException; import org.springframework.batch.core.launch.JobLauncher; import org.springframework.batch.core.repository.JobExecutionAlreadyRunningException; import org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException; import org.springframework.batch.core.repository.JobRestartException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; @Component public class RunScheduler { @Autowired private JobLauncher jobLauncher; @Autowired private Job job; @Scheduled(cron = "${cron.job.expression}") public void run() { try { JobParameters jobParameters = new JobParametersBuilder() .addLong("time", System.currentTimeMillis()) .toJobParameters(); JobExecution execution = jobLauncher.run(job, jobParameters); System.out.println("Exit status : " + execution.getStatus()); } catch (JobInstanceAlreadyCompleteException e) { e.printStackTrace(); } catch (JobExecutionAlreadyRunningException e) { e.printStackTrace(); } catch (JobParametersInvalidException e) { e.printStackTrace(); } catch (JobRestartException e) { e.printStackTrace(); } } }
Spring Batch Jobs
CSV file
100,walkingtechie.blogspot.com 200,stackoverflow.com 300,oracle.com
This is job which will read the CSV file and write using the custom writer.
package com.walking.techie.taskscheduler.jobs; import com.walking.techie.taskscheduler.model.Domain; import com.walking.techie.taskscheduler.scheduler.RunScheduler; import com.walking.techie.taskscheduler.writer.CustomWriter; import org.springframework.batch.core.Job; import org.springframework.batch.core.Step; 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.item.file.FlatFileItemReader; import org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper; import org.springframework.batch.item.file.mapping.DefaultLineMapper; import org.springframework.batch.item.file.transform.DelimitedLineTokenizer; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.ClassPathResource; @Configuration @EnableBatchProcessing public class ScheduledDomainJob { @Autowired private JobBuilderFactory jobBuilderFactory; @Autowired private StepBuilderFactory stepBuilderFactory; @Bean public Job scheduledJob() { return jobBuilderFactory.get("scheduledJob").flow(step1()).end().build(); } @Bean public Step step1() { return stepBuilderFactory.get("step1").<Domain, Domain>chunk(10) .reader(reader()).writer(writer()).build(); } @Bean public FlatFileItemReader<Domain> reader() { FlatFileItemReader<Domain> reader = new FlatFileItemReader<>(); reader.setResource(new ClassPathResource("csv/domain-1-03-2017.csv")); reader.setLineMapper(new DefaultLineMapper<Domain>() {{ setLineTokenizer(new DelimitedLineTokenizer() {{ setNames(new String[]{"id", "domain"}); }}); setFieldSetMapper(new BeanWrapperFieldSetMapper<Domain>() {{ setTargetType(Domain.class); }}); }}); return reader; } @Bean public CustomWriter writer() { CustomWriter writer = new CustomWriter(); return writer; } @Bean public RunScheduler scheduler() { RunScheduler scheduler = new RunScheduler(); return scheduler; } }
Map record from CSV file to Domain
object and write using CustomWriter
.
A Java model class
package com.walking.techie.taskscheduler.model; import lombok.Data; import lombok.ToString; @Data @ToString public class Domain { private int id; private String domain; }
A CustomWriter
will simply print the domain on the console.
package com.walking.techie.taskscheduler.writer; import com.walking.techie.taskscheduler.model.Domain; import java.util.List; import lombok.extern.slf4j.Slf4j; import org.springframework.batch.item.ItemWriter; @Slf4j public class CustomWriter implements ItemWriter<Domain> { @Override public void write(List<? extends Domain> items) throws Exception { log.info("writer ....... " + items.size()); for (Domain domain : items) { log.info(domain + "\n"); } } }
Run Application
package com.walking.techie; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; @SpringBootApplication(exclude = DataSourceAutoConfiguration.class) @EnableScheduling public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
Output
The Job will run on every 10 seconds and print something like below on console.
output on console
2017-03-29 17:30:37.848 INFO 40071 --- [ main] o.s.b.c.l.support.SimpleJobLauncher : Job: [FlowJob: [name=scheduledJob]] launched with the following parameters: [{}] 2017-03-29 17:30:37.866 INFO 40071 --- [ main] o.s.batch.core.job.SimpleStepHandler : Executing step: [step1] 2017-03-29 17:30:37.882 INFO 40071 --- [ main] c.w.t.taskscheduler.writer.CustomWriter : writer ....... 3 2017-03-29 17:30:37.882 INFO 40071 --- [ main] c.w.t.taskscheduler.writer.CustomWriter : Domain(id=100, domain=walkingtechie.blogspot.com) 2017-03-29 17:30:37.882 INFO 40071 --- [ main] c.w.t.taskscheduler.writer.CustomWriter : Domain(id=200, domain=stackoverflow.com) 2017-03-29 17:30:37.882 INFO 40071 --- [ main] c.w.t.taskscheduler.writer.CustomWriter : Domain(id=300, domain=oracle.com) 2017-03-29 17:30:37.893 INFO 40071 --- [ main] o.s.b.c.l.support.SimpleJobLauncher : Job: [FlowJob: [name=scheduledJob]] completed with the following parameters: [{}] and the following status: [COMPLETED] 2017-03-29 17:30:37.895 INFO 40071 --- [ main] com.walking.techie.Application : Started Application in 11.432 seconds (JVM running for 11.9) 2017-03-29 17:30:40.009 INFO 40071 --- [pool-1-thread-1] o.s.b.c.l.support.SimpleJobLauncher : Job: [FlowJob: [name=scheduledJob]] launched with the following parameters: [{time=1490788840004}] 2017-03-29 17:30:40.019 INFO 40071 --- [pool-1-thread-1] o.s.batch.core.job.SimpleStepHandler : Executing step: [step1] 2017-03-29 17:30:40.023 INFO 40071 --- [pool-1-thread-1] c.w.t.taskscheduler.writer.CustomWriter : writer ....... 3 2017-03-29 17:30:40.023 INFO 40071 --- [pool-1-thread-1] c.w.t.taskscheduler.writer.CustomWriter : Domain(id=100, domain=walkingtechie.blogspot.com) 2017-03-29 17:30:40.023 INFO 40071 --- [pool-1-thread-1] c.w.t.taskscheduler.writer.CustomWriter : Domain(id=200, domain=stackoverflow.com) 2017-03-29 17:30:40.023 INFO 40071 --- [pool-1-thread-1] c.w.t.taskscheduler.writer.CustomWriter : Domain(id=300, domain=oracle.com) 2017-03-29 17:30:40.029 INFO 40071 --- [pool-1-thread-1] o.s.b.c.l.support.SimpleJobLauncher : Job: [FlowJob: [name=scheduledJob]] completed with the following parameters: [{time=1490788840004}] and the following status: [COMPLETED] Exit status : COMPLETED 2017-03-29 17:30:40.031 INFO 40071 --- [pool-1-thread-1] o.s.b.c.l.support.SimpleJobLauncher : Job: [FlowJob: [name=scheduledJob]] launched with the following parameters: [{time=1490788840030}] 2017-03-29 17:30:40.035 INFO 40071 --- [pool-1-thread-1] o.s.batch.core.job.SimpleStepHandler : Executing step: [step1] 2017-03-29 17:30:40.038 INFO 40071 --- [pool-1-thread-1] c.w.t.taskscheduler.writer.CustomWriter : writer ....... 3 2017-03-29 17:30:40.038 INFO 40071 --- [pool-1-thread-1] c.w.t.taskscheduler.writer.CustomWriter : Domain(id=100, domain=walkingtechie.blogspot.com) 2017-03-29 17:30:40.038 INFO 40071 --- [pool-1-thread-1] c.w.t.taskscheduler.writer.CustomWriter : Domain(id=200, domain=stackoverflow.com) 2017-03-29 17:30:40.038 INFO 40071 --- [pool-1-thread-1] c.w.t.taskscheduler.writer.CustomWriter : Domain(id=300, domain=oracle.com) 2017-03-29 17:30:40.045 INFO 40071 --- [pool-1-thread-1] o.s.b.c.l.support.SimpleJobLauncher : Job: [FlowJob: [name=scheduledJob]] completed with the following parameters: [{time=1490788840030}] and the following status: [COMPLETED] Exit status : COMPLETED
Note : This code has been compiled and run on mac notebook and intellij IDEA.
very special. easy to understand…. taking things from root .. stay blessed
ReplyDeleteWe have an excellent IT courses training institute in Hyderabad. We are offering a number of courses that are very trendy in the IT industry. For further information.
spring boot online training india!