随着项目的规模的不断扩大,Spring Batch的配置文件,也是一个头疼的问题,本人试了很多次,建议的配置方式如下:
基础配置放在一个文件中applicationContext-batch.xml:
<beans:beans xmlns="http://www.springframework.org/schema/batch" xmlns:beans="http://www.springframework.org/schema/beans" xmlns:bean="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch-2.1.xsd"> <bean:bean id="jobRepository" class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean"> <bean:property name="transactionManager" ref="transactionManager" /> </bean:bean> <bean:bean id="transactionManager" class="org.springframework.batch.support.transaction.ResourcelessTransactionManager"> </bean:bean> <bean:bean id="jobLauncher" class="org.springframework.batch.core.launch.support.SimpleJobLauncher"> <bean:property name="jobRepository" ref="jobRepository" /> <bean:property name="taskExecutor"> <bean:bean class="org.springframework.core.task.SimpleAsyncTaskExecutor"></bean:bean> </bean:property> </bean:bean> </beans:beans>
<beans:beans xmlns="http://www.springframework.org/schema/batch" xmlns:beans="http://www.springframework.org/schema/beans" xmlns:bean="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch-2.1.xsd"> <flow id="mysteps_flow"> <step id="mysteps_flow_first" parent="mysteps_first" next="mysteps_flow_second"></step> <step id="mysteps_flow_second" parent="mysteps_second" next="mysteps_flow_third"></step> <step id="mysteps_flow_third" parent="mysteps_third"></step> </flow> <step id="mysteps_first"> <tasklet ref="first"></tasklet> </step> <step id="mysteps_second"> <tasklet ref="second"></tasklet> </step> <step id="mysteps_third"> <tasklet ref="third"></tasklet> </step> <bean:bean id="first" class="com.test.tasklet.MyFirstTasklet" scope="step"> </bean:bean> <bean:bean id="second" class="com.test.tasklet.MySecondTasklet" scope="step"> </bean:bean> <bean:bean id="third" class="com.test.tasklet.MyThirdTasklet" scope="step"> </bean:bean> </beans:beans>
所有的Job放在同一个配置文件中applicationContext-batch-job.xml:
<beans:beans xmlns="http://www.springframework.org/schema/batch" xmlns:beans="http://www.springframework.org/schema/beans" xmlns:bean="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch-2.1.xsd"> <job id="fJob"> <step id="fJob_begin" parent="mysteps_first" next="fJob_second"></step> <flow id="fJob_second" parent="mysteps_flow"></flow> </job> <job id="sJob"> <step id="sJob_begin" parent="mysteps_first"></step> </job> </beans:beans>
一个Flow是一些Steps的集合,用好parent属性,parent可以让一个step或者flow继承父元素的所有属性。
main函数:
/** * */ package com.test.springbatch; import org.springframework.batch.core.ExitStatus; import org.springframework.batch.core.Job; import org.springframework.batch.core.JobExecution; 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.context.ApplicationContext; import org.springframework.context.support.FileSystemXmlApplicationContext; /** * @author hadoop * */ public class AppMain { /** * @param args */ public static void main(String[] args) { ApplicationContext context; JobParametersBuilder jobPara = new JobParametersBuilder(); //设置文件路径参数 context = new FileSystemXmlApplicationContext(new String[]{"classpath:applicationContext-batch-mysteps.xml", "classpath:applicationContext-batch.xml", "classpath:applicationContext-batch-job.xml"}); Job fJob = (Job)context.getBean("fJob"); Job sJob = (Job)context.getBean("sJob"); JobLauncher launcher = (JobLauncher)context.getBean("jobLauncher"); try { launcher.run(fJob, jobPara.toJobParameters()); //launcher.run(sJob, jobPara.toJobParameters()); } catch (JobExecutionAlreadyRunningException e) { e.printStackTrace(); } catch (JobRestartException e) { e.printStackTrace(); } catch (JobInstanceAlreadyCompleteException e) { e.printStackTrace(); } catch (JobParametersInvalidException e) { e.printStackTrace(); } } }
/** * */ package com.test.tasklet; import org.springframework.batch.core.StepContribution; import org.springframework.batch.core.scope.context.ChunkContext; import org.springframework.batch.core.step.tasklet.Tasklet; import org.springframework.batch.repeat.RepeatStatus; /** * @author hadoop * */ public class MyFirstTasklet implements Tasklet { /* (non-Javadoc) * @see org.springframework.batch.core.step.tasklet.Tasklet#execute(org.springframework.batch.core.StepContribution, org.springframework.batch.core.scope.context.ChunkContext) */ public RepeatStatus execute(StepContribution arg0, ChunkContext arg1) throws Exception { for(int i = 0; i < 10; i++) { System.out.println(Thread.currentThread().getName() + "F" + i); Thread.sleep(1000); } return RepeatStatus.FINISHED; } }
/** * */ package com.test.tasklet; import org.springframework.batch.core.StepContribution; import org.springframework.batch.core.scope.context.ChunkContext; import org.springframework.batch.core.step.tasklet.Tasklet; import org.springframework.batch.repeat.RepeatStatus; /** * @author hadoop * */ public class MySecondTasklet implements Tasklet { /* (non-Javadoc) * @see org.springframework.batch.core.step.tasklet.Tasklet#execute(org.springframework.batch.core.StepContribution, org.springframework.batch.core.scope.context.ChunkContext) */ public RepeatStatus execute(StepContribution arg0, ChunkContext arg1) throws Exception { for(int i = 0; i < 10; i++) { System.out.println(Thread.currentThread().getName() + "S" + i); Thread.sleep(1000); } return RepeatStatus.FINISHED; } }
/** * */ package com.test.tasklet; import org.springframework.batch.core.StepContribution; import org.springframework.batch.core.scope.context.ChunkContext; import org.springframework.batch.core.step.tasklet.Tasklet; import org.springframework.batch.repeat.RepeatStatus; /** * @author hadoop * */ public class MyThirdTasklet implements Tasklet { /* (non-Javadoc) * @see org.springframework.batch.core.step.tasklet.Tasklet#execute(org.springframework.batch.core.StepContribution, org.springframework.batch.core.scope.context.ChunkContext) */ public RepeatStatus execute(StepContribution arg0, ChunkContext arg1) throws Exception { for(int i = 0; i < 10; i++) { System.out.println(Thread.currentThread().getName() + "T" + i); Thread.sleep(1000); } return RepeatStatus.FINISHED; } }
INFO [org.springframework.context.support.FileSystemXmlApplicationContext] - Refreshing org.springframework.context.support.FileSystemXmlApplicationContext@68fe748f: display name [org.springframework.context.support.FileSystemXmlApplicationContext@68fe748f]; startup date [Sat May 04 09:46:27 CST 2013]; root of context hierarchy INFO [org.springframework.beans.factory.xml.XmlBeanDefinitionReader] - Loading XML bean definitions from class path resource [applicationContext-batch-mysteps.xml] INFO [org.springframework.beans.factory.xml.XmlBeanDefinitionReader] - Loading XML bean definitions from class path resource [applicationContext-batch.xml] INFO [org.springframework.beans.factory.xml.XmlBeanDefinitionReader] - Loading XML bean definitions from class path resource [applicationContext-batch-job.xml] INFO [org.springframework.beans.factory.support.DefaultListableBeanFactory] - Overriding bean definition for bean 'fJob': replacing [Generic bean: class [org.springframework.batch.core.configuration.xml.SimpleFlowFactoryBean]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null] with [Generic bean: class [org.springframework.batch.core.configuration.xml.JobParserJobFactoryBean]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null] INFO [org.springframework.beans.factory.support.DefaultListableBeanFactory] - Overriding bean definition for bean 'sJob': replacing [Generic bean: class [org.springframework.batch.core.configuration.xml.SimpleFlowFactoryBean]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null] with [Generic bean: class [org.springframework.batch.core.configuration.xml.JobParserJobFactoryBean]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null] INFO [org.springframework.context.support.FileSystemXmlApplicationContext] - Bean factory for application context [org.springframework.context.support.FileSystemXmlApplicationContext@68fe748f]: org.springframework.beans.factory.support.DefaultListableBeanFactory@1232784a INFO [org.springframework.beans.factory.support.DefaultListableBeanFactory] - Overriding bean definition for bean 'first': replacing [Generic bean: class [com.test.tasklet.MyFirstTasklet]; scope=step; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=false; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in class path resource [applicationContext-batch-mysteps.xml]] with [Root bean: class [org.springframework.batch.core.scope.util.PlaceholderProxyFactoryBean]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in BeanDefinition defined in class path resource [applicationContext-batch-mysteps.xml]] INFO [org.springframework.beans.factory.support.DefaultListableBeanFactory] - Overriding bean definition for bean 'second': replacing [Generic bean: class [com.test.tasklet.MySecondTasklet]; scope=step; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=false; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in class path resource [applicationContext-batch-mysteps.xml]] with [Root bean: class [org.springframework.batch.core.scope.util.PlaceholderProxyFactoryBean]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in BeanDefinition defined in class path resource [applicationContext-batch-mysteps.xml]] INFO [org.springframework.beans.factory.support.DefaultListableBeanFactory] - Overriding bean definition for bean 'third': replacing [Generic bean: class [com.test.tasklet.MyThirdTasklet]; scope=step; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=false; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in class path resource [applicationContext-batch-mysteps.xml]] with [Root bean: class [org.springframework.batch.core.scope.util.PlaceholderProxyFactoryBean]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in BeanDefinition defined in class path resource [applicationContext-batch-mysteps.xml]] INFO [org.springframework.beans.factory.support.DefaultListableBeanFactory] - Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@1232784a: defining beans [org.springframework.batch.core.scope.internalStepScope,org.springframework.beans.factory.config.CustomEditorConfigurer,org.springframework.batch.core.configuration.xml.CoreNamespacePostProcessor,mysteps_flow_first,mysteps_flow_second,mysteps_flow_third,mysteps_flow,mysteps_first,mysteps_second,mysteps_third,first,second,third,jobRepository,transactionManager,jobLauncher,fJob_begin,fJob,sJob_begin,sJob,lazyBindingProxy.first,lazyBindingProxy.second,lazyBindingProxy.third]; root of factory hierarchy INFO [org.springframework.batch.core.launch.support.SimpleJobLauncher] - Job: [FlowJob: [name=fJob]] launched with the following parameters: [{}] INFO [org.springframework.batch.core.job.SimpleStepHandler] - Executing step: [fJob_begin] SimpleAsyncTaskExecutor-1F0 SimpleAsyncTaskExecutor-1F1 SimpleAsyncTaskExecutor-1F2 SimpleAsyncTaskExecutor-1F3 SimpleAsyncTaskExecutor-1F4 SimpleAsyncTaskExecutor-1F5 SimpleAsyncTaskExecutor-1F6 SimpleAsyncTaskExecutor-1F7 SimpleAsyncTaskExecutor-1F8 SimpleAsyncTaskExecutor-1F9 INFO [org.springframework.batch.core.job.SimpleStepHandler] - Executing step: [mysteps_flow_first] SimpleAsyncTaskExecutor-1F0 SimpleAsyncTaskExecutor-1F1 SimpleAsyncTaskExecutor-1F2 SimpleAsyncTaskExecutor-1F3 SimpleAsyncTaskExecutor-1F4 SimpleAsyncTaskExecutor-1F5 SimpleAsyncTaskExecutor-1F6 SimpleAsyncTaskExecutor-1F7 SimpleAsyncTaskExecutor-1F8 SimpleAsyncTaskExecutor-1F9 INFO [org.springframework.batch.core.job.SimpleStepHandler] - Executing step: [mysteps_flow_second] SimpleAsyncTaskExecutor-1S0 SimpleAsyncTaskExecutor-1S1 SimpleAsyncTaskExecutor-1S2 SimpleAsyncTaskExecutor-1S3 SimpleAsyncTaskExecutor-1S4 SimpleAsyncTaskExecutor-1S5 SimpleAsyncTaskExecutor-1S6 SimpleAsyncTaskExecutor-1S7 SimpleAsyncTaskExecutor-1S8 SimpleAsyncTaskExecutor-1S9 INFO [org.springframework.batch.core.job.SimpleStepHandler] - Executing step: [mysteps_flow_third] SimpleAsyncTaskExecutor-1T0 SimpleAsyncTaskExecutor-1T1 SimpleAsyncTaskExecutor-1T2 SimpleAsyncTaskExecutor-1T3 SimpleAsyncTaskExecutor-1T4 SimpleAsyncTaskExecutor-1T5 SimpleAsyncTaskExecutor-1T6 SimpleAsyncTaskExecutor-1T7 SimpleAsyncTaskExecutor-1T8 SimpleAsyncTaskExecutor-1T9 INFO [org.springframework.batch.core.launch.support.SimpleJobLauncher] - Job: [FlowJob: [name=fJob]] completed with the following parameters: [{}] and the following status: [COMPLETED]