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]

發佈了55 篇原創文章 · 獲贊 6 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章