Spring batch的自动运行
程序员文章站
2022-06-14 18:57:23
...
一个最简单的spring batch的程序,照办官网的sample,如下
一个配置程序
@Configuration @EnableBatchProcessing @EnableAutoConfiguration public class BatchConfiguration { @Autowired private JobBuilderFactory jobBuilderFactory; @Autowired private StepBuilderFactory stepBuilderFactory; @Bean public Step step1() { return stepBuilderFactory.get("step1") .tasklet(new Tasklet() { public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) { return null; } }) .build(); } @Bean public Job job(Step step1) throws Exception { return jobBuilderFactory.get("job1") .incrementer(new RunIdIncrementer()) .start(step1) .build(); } }
一个主程序
public class Main { public static void main(String [] args) { System.exit(SpringApplication.exit(SpringApplication.run( BatchConfiguration.class, args))); } }
你肯定会好奇,为啥Job就执行了呢?没看到调用啊
实际上在Spring batch的配置程序org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration里有以下代码
@Bean @ConditionalOnMissingBean @ConditionalOnProperty(prefix = "spring.batch.job", name = "enabled", havingValue = "true", matchIfMissing = true) public JobLauncherCommandLineRunner jobLauncherCommandLineRunner( JobLauncher jobLauncher, JobExplorer jobExplorer) { JobLauncherCommandLineRunner runner = new JobLauncherCommandLineRunner( jobLauncher, jobExplorer); String jobNames = this.properties.getJob().getNames(); if (StringUtils.hasText(jobNames)) { runner.setJobNames(jobNames); } return runner; }
也就是当配置文件里定义spring.batch.job.enabled为true,或者没定义(默认为true)的时候,会初始化一个JobLauncherCommandLineRunner的bean。
而在SpringApplication里有以下代码
private void callRunners(ApplicationContext context, ApplicationArguments args) { List<Object> runners = new ArrayList<Object>(); runners.addAll(context.getBeansOfType(ApplicationRunner.class).values()); runners.addAll(context.getBeansOfType(CommandLineRunner.class).values()); AnnotationAwareOrderComparator.sort(runners); for (Object runner : new LinkedHashSet<Object>(runners)) { if (runner instanceof ApplicationRunner) { callRunner((ApplicationRunner) runner, args); } if (runner instanceof CommandLineRunner) { callRunner((CommandLineRunner) runner, args); } } }
也就是只要能找到ApplicationRunner或者CommandLineRunner的子类,就挨个执行。
默认是没有ApplicationRunner的子类的,而CommandLineRunner得子类就是JobLauncherCommandLineRunner了,所以会执行所配置的job。
如果想自己执行job的话,使用以下代码便可。
@Autowired private JobLauncher jobLauncher; @Autowired private Job job; @Scheduled(initialDelay=3000,fixedRate = 1000) public void run(){ try { JobExecution execution = jobLauncher.run(job, new JobParameters()); System.out.println("Execution status: "+ execution.getStatus()); } catch (JobExecutionAlreadyRunningException | JobRestartException | JobInstanceAlreadyCompleteException | JobParametersInvalidException e) { e.printStackTrace(); } }
这时候,你可能会好奇,JobLauncher是哪儿配置的?
上面的配置文件里使用了注解@EnableBatchProcessing
这个注解会初始化以下所有bean
写道
JobRepository bean 名称 "jobRepository"
JobLauncher bean名称"jobLauncher"
JobRegistry bean名称"jobRegistry"
PlatformTransactionManager bean名称 "transactionManager"
JobBuilderFactory bean名称"jobBuilders"
StepBuilderFactory bean名称"stepBuilders"
JobLauncher bean名称"jobLauncher"
JobRegistry bean名称"jobRegistry"
PlatformTransactionManager bean名称 "transactionManager"
JobBuilderFactory bean名称"jobBuilders"
StepBuilderFactory bean名称"stepBuilders"
在程序org.springframework.batch.core.configuration.annotation.BatchConfigurationSelector会根据定义选择配置程序,默认用的是SimpleBatchConfiguration
public class BatchConfigurationSelector implements ImportSelector { @Override public String[] selectImports(AnnotationMetadata importingClassMetadata) { Class<?> annotationType = EnableBatchProcessing.class; AnnotationAttributes attributes = AnnotationAttributes.fromMap(importingClassMetadata.getAnnotationAttributes( annotationType.getName(), false)); Assert.notNull(attributes, String.format("@%s is not present on importing class '%s' as expected", annotationType.getSimpleName(), importingClassMetadata.getClassName())); String[] imports; if (attributes.containsKey("modular") && attributes.getBoolean("modular")) { imports = new String[] { ModularBatchConfiguration.class.getName() }; } else { imports = new String[] { SimpleBatchConfiguration.class.getName() }; } return imports; } }
推荐阅读
-
Spring boot中@Conditional和spring boot的自动配置实例详解
-
spring入门教程之bean的继承与自动装配详解
-
Spring自动扫描无法扫描jar包中bean的解决方法
-
Spring和MyBatis整合自动生成代码里面text类型遇到的坑
-
Spring boot中@Conditional和spring boot的自动配置实例详解
-
Spring自动扫描无法扫描jar包中bean的解决方法
-
spring boot项目打包成war在tomcat运行的全步骤
-
Spring和MyBatis整合自动生成代码里面text类型遇到的坑
-
Spring Data Jpa 自动生成表结构的方法示例
-
详解如何在低版本的Spring中快速实现类似自动配置的功能