Spring Batch规划好你的配置文件,用好Flow

随着项目的规模的不断扩大,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>

一个业务场景对应一个配置文件applicationContext-batch-mysteps.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">
	
	<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>

业务场景的配置,最好到Flow级别。

所有的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>

这样,我们只需要看Job的配置文件就能看到所有的可以执行的Job。

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

}

三个task类:

/**
 * 
 */
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]

你可能感兴趣的:(spring,配置,batch,flow)