– Start
点击此处观看本系列配套视频。
下面的例子定义了一个叫做 EndOfJob 的 Job,它仅仅运行一条命令。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xmlns:batch="http://www.springframework.org/schema/batch"
xsi:schemaLocation="http://www.springframework.org/schema/batch
http://www.springframework.org/schema/batch/spring-batch.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 定义 dataSource -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
<property name="url" value="jdbc:oracle:thin:@localhost:1521:xe" />
<property name="username" value="hr" />
<property name="password" value="123456" />
</bean>
<!-- 定义 jdbc 事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 定义 jobRepository, 用来持久化 job -->
<batch:job-repository id="jobRepository" data-source="dataSource" transaction-manager="transactionManager"/>
<!-- 定义 jobLauncher, 来用运行 job -->
<bean id="jobLauncher" class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
<property name="jobRepository" ref="jobRepository" />
</bean>
<!-- 定义 job -->
<batch:job id="EndOfJob" job-repository="jobRepository">
<batch:step id="EndOfStep">
<batch:tasklet ref="endOfTasklet"/>
</batch:step>
</batch:job>
<!-- 定义 tasklet -->
<bean id="endOfTasklet" class="org.springframework.batch.core.step.tasklet.SystemCommandTasklet" scope="step">
<property name="command" value="java -version" />
<property name="timeout" value="50000" />
</bean>
</beans>
package shangbo.springbatch.example1;
import java.util.HashMap;
import java.util.Map;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobParameter;
import org.springframework.batch.core.JobParameters;
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.ClassPathXmlApplicationContext;
public class App {
public static void main(String[] args) throws JobExecutionAlreadyRunningException, JobRestartException, JobInstanceAlreadyCompleteException, JobParametersInvalidException {
ApplicationContext context = new ClassPathXmlApplicationContext("shangbo/springbatch/example1/EndOfJob.xml");
// job 和 job 参数
Map<String,JobParameter> parameters = new HashMap<>();
parameters.put("business_date", new JobParameter("20170505"));
JobParameters jobParameters = new JobParameters(parameters);
Job job = context.getBean(Job.class);
// 运行 job
JobLauncher jobLauncher = context.getBean(JobLauncher.class);
jobLauncher.run(job, jobParameters);
}
}
运行上面的例子得到如下输出。
七月 13, 2017 9:04:40 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@22d8cfe0: startup date [Thu Jul 13 21:04:40 CST 2017]; root of context hierarchy
七月 13, 2017 9:04:40 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [shangbo/springbatch/example1/EndOfJob.xml]
七月 13, 2017 9:04:40 下午 org.springframework.beans.factory.support.DefaultListableBeanFactory registerBeanDefinition
信息: Overriding bean definition for bean 'endOfTasklet': replacing [Generic bean: class [org.springframework.batch.core.step.tasklet.SystemCommandTasklet]; 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 [shangbo/springbatch/example1/EndOfJob.xml]] with [Root bean: class [org.springframework.aop.scope.ScopedProxyFactoryBean]; scope=; 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 [shangbo/springbatch/example1/EndOfJob.xml]]
七月 13, 2017 9:04:41 下午 org.springframework.batch.core.repository.support.JobRepositoryFactoryBean afterPropertiesSet
信息: No database type set, using meta data indicating: ORACLE
七月 13, 2017 9:04:41 下午 org.springframework.batch.core.launch.support.SimpleJobLauncher afterPropertiesSet
信息: No TaskExecutor has been set, defaulting to synchronous executor.
七月 13, 2017 9:04:41 下午 org.springframework.batch.core.launch.support.SimpleJobLauncher run
信息: Job: [FlowJob: [name=EndOfJob]] launched with the following parameters: [{business_date=20170505}]
七月 13, 2017 9:04:41 下午 org.springframework.batch.core.job.SimpleStepHandler handleStep
信息: Executing step: [EndOfStep]
七月 13, 2017 9:04:42 下午 org.springframework.batch.core.launch.support.SimpleJobLauncher run
信息: Job: [FlowJob: [name=EndOfJob]] completed with the following parameters: [{business_date=20170505}] and the following status: [COMPLETED]
如果你再次运行这个例子,得到如下输出。
七月 13, 2017 9:05:56 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@22d8cfe0: startup date [Thu Jul 13 21:05:56 CST 2017]; root of context hierarchy
七月 13, 2017 9:05:56 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [shangbo/springbatch/example1/EndOfJob.xml]
七月 13, 2017 9:05:56 下午 org.springframework.beans.factory.support.DefaultListableBeanFactory registerBeanDefinition
信息: Overriding bean definition for bean 'endOfTasklet': replacing [Generic bean: class [org.springframework.batch.core.step.tasklet.SystemCommandTasklet]; 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 [shangbo/springbatch/example1/EndOfJob.xml]] with [Root bean: class [org.springframework.aop.scope.ScopedProxyFactoryBean]; scope=; 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 [shangbo/springbatch/example1/EndOfJob.xml]]
七月 13, 2017 9:05:57 下午 org.springframework.batch.core.repository.support.JobRepositoryFactoryBean afterPropertiesSet
信息: No database type set, using meta data indicating: ORACLE
七月 13, 2017 9:05:57 下午 org.springframework.batch.core.launch.support.SimpleJobLauncher afterPropertiesSet
信息: No TaskExecutor has been set, defaulting to synchronous executor.
Exception in thread "main" org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException: A job instance already exists and is complete for parameters={business_date=20170505}. If you want to run this job again, change the parameters.
at org.springframework.batch.core.repository.support.SimpleJobRepository.createJobExecution(SimpleJobRepository.java:126)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:98)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:262)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.batch.core.repository.support.AbstractJobRepositoryFactoryBean$1.invoke(AbstractJobRepositoryFactoryBean.java:172)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
at com.sun.proxy.$Proxy4.createJobExecution(Unknown Source)
at org.springframework.batch.core.launch.support.SimpleJobLauncher.run(SimpleJobLauncher.java:125)
at shangbo.springbatch.example1.App.main(App.java:29)
为什么会错呢?别着急你很快就会知道。
– 更多参见:Spring Batch 精萃
– 声 明:转载请注明出处
– Last Updated on 2017-07-13
– Written by ShangBo on 2017-07-13
– End