Automatic running of Spring batch

One of the simplest spring batch programs, follow the sample on the official website , as follows

a configurator

 

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

 

 

 a main program

 

public class Main {
  public static void main(String [] args) {
    System.exit(SpringApplication.exit(SpringApplication.run(
        BatchConfiguration.class, args)));
  }
}

 You must be curious, why is the Job executed? I don't see the call

 

In fact, there is the following code in the Spring batch configuration program 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;
	}

 

 

That is, when spring.batch.job.enabled is defined as true in the configuration file , or not defined (default is true), a JobLauncherCommandLineRunner bean will be initialized.

And in SpringApplication there is the following code

 

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

 That is, as long as you can find a subclass of ApplicationRunner or CommandLineRunner, execute them one by one.

 

By default, there is no subclass of ApplicationRunner, and the subclass of CommandLineRunner is JobLauncherCommandLineRunner, so the configured job will be executed.

If you want to execute the job yourself, use the following code.

 

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

 At this point, you may be wondering, where is the JobLauncher configured?

 

The above configuration file uses the annotation @EnableBatchProcessing

This annotation will initialize all the following beans

 

wrote

 

JobRepository bean 名称 "jobRepository"
JobLauncher bean名称"jobLauncher"
JobRegistry bean名称"jobRegistry"
PlatformTransactionManager bean名称 "transactionManager"
JobBuilderFactory bean名称"jobBuilders"
StepBuilderFactory bean名称"stepBuilders"

 In the program org.springframework.batch.core.configuration.annotation.BatchConfigurationSelector will select the configuration program according to the definition, the default is 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;
	}

}

 

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326800556&siteId=291194637