001/* 002 * Copyright 2012-2018 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.boot.autoconfigure.batch; 018 019import javax.sql.DataSource; 020 021import org.springframework.batch.core.configuration.ListableJobLocator; 022import org.springframework.batch.core.converter.JobParametersConverter; 023import org.springframework.batch.core.explore.JobExplorer; 024import org.springframework.batch.core.launch.JobLauncher; 025import org.springframework.batch.core.launch.JobOperator; 026import org.springframework.batch.core.launch.support.SimpleJobOperator; 027import org.springframework.batch.core.repository.JobRepository; 028import org.springframework.beans.factory.ObjectProvider; 029import org.springframework.boot.ExitCodeGenerator; 030import org.springframework.boot.autoconfigure.AutoConfigureAfter; 031import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 032import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; 033import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; 034import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 035import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 036import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; 037import org.springframework.boot.context.properties.EnableConfigurationProperties; 038import org.springframework.context.annotation.Bean; 039import org.springframework.context.annotation.Configuration; 040import org.springframework.context.annotation.Import; 041import org.springframework.core.io.ResourceLoader; 042import org.springframework.jdbc.core.JdbcOperations; 043import org.springframework.util.StringUtils; 044 045/** 046 * {@link EnableAutoConfiguration Auto-configuration} for Spring Batch. By default a 047 * Runner will be created and all jobs in the context will be executed on startup. 048 * <p> 049 * Disable this behavior with {@literal spring.batch.job.enabled=false}). 050 * <p> 051 * Alternatively, discrete Job names to execute on startup can be supplied by the User 052 * with a comma-delimited list: {@literal spring.batch.job.names=job1,job2}. In this case 053 * the Runner will first find jobs registered as Beans, then those in the existing 054 * JobRegistry. 055 * 056 * @author Dave Syer 057 * @author Eddú Meléndez 058 * @author Kazuki Shimizu 059 * @author Mahmoud Ben Hassine 060 */ 061@Configuration 062@ConditionalOnClass({ JobLauncher.class, DataSource.class, JdbcOperations.class }) 063@AutoConfigureAfter(HibernateJpaAutoConfiguration.class) 064@ConditionalOnBean(JobLauncher.class) 065@EnableConfigurationProperties(BatchProperties.class) 066@Import(BatchConfigurerConfiguration.class) 067public class BatchAutoConfiguration { 068 069 private final BatchProperties properties; 070 071 private final JobParametersConverter jobParametersConverter; 072 073 public BatchAutoConfiguration(BatchProperties properties, 074 ObjectProvider<JobParametersConverter> jobParametersConverter) { 075 this.properties = properties; 076 this.jobParametersConverter = jobParametersConverter.getIfAvailable(); 077 } 078 079 @Bean 080 @ConditionalOnMissingBean 081 @ConditionalOnBean(DataSource.class) 082 public BatchDataSourceInitializer batchDataSourceInitializer(DataSource dataSource, 083 ResourceLoader resourceLoader) { 084 return new BatchDataSourceInitializer(dataSource, resourceLoader, 085 this.properties); 086 } 087 088 @Bean 089 @ConditionalOnMissingBean 090 @ConditionalOnProperty(prefix = "spring.batch.job", name = "enabled", havingValue = "true", matchIfMissing = true) 091 public JobLauncherCommandLineRunner jobLauncherCommandLineRunner( 092 JobLauncher jobLauncher, JobExplorer jobExplorer, 093 JobRepository jobRepository) { 094 JobLauncherCommandLineRunner runner = new JobLauncherCommandLineRunner( 095 jobLauncher, jobExplorer, jobRepository); 096 String jobNames = this.properties.getJob().getNames(); 097 if (StringUtils.hasText(jobNames)) { 098 runner.setJobNames(jobNames); 099 } 100 return runner; 101 } 102 103 @Bean 104 @ConditionalOnMissingBean(ExitCodeGenerator.class) 105 public JobExecutionExitCodeGenerator jobExecutionExitCodeGenerator() { 106 return new JobExecutionExitCodeGenerator(); 107 } 108 109 @Bean 110 @ConditionalOnMissingBean(JobOperator.class) 111 public SimpleJobOperator jobOperator(JobExplorer jobExplorer, JobLauncher jobLauncher, 112 ListableJobLocator jobRegistry, JobRepository jobRepository) 113 throws Exception { 114 SimpleJobOperator factory = new SimpleJobOperator(); 115 factory.setJobExplorer(jobExplorer); 116 factory.setJobLauncher(jobLauncher); 117 factory.setJobRegistry(jobRegistry); 118 factory.setJobRepository(jobRepository); 119 if (this.jobParametersConverter != null) { 120 factory.setJobParametersConverter(this.jobParametersConverter); 121 } 122 return factory; 123 } 124 125}