Tuesday, August 5, 2014

Spring scheduler launches multiple jobs

1. spring configuration file app-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:task="http://www.springframework.org/schema/task" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/jdbc
http://www.springframework.org/schema/jdbc/spring-jdbc-3.1.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.1.xsd">

<context:component-scan base-package="wx.batch1" />

<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/testdb2" />
<property name="username" value="tester2" />
<property name="password" value="abcd1234" />
</bean>
       <!-- use mysql to store spring batch meta data -->
<bean id="jobRepository"
class="org.springframework.batch.core.repository.support.JobRepositoryFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="transactionManager" ref="transactionManager" />
<property name="databaseType" value="mysql" />
</bean>

<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>

<bean id="jobLauncher"
class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
<property name="jobRepository" ref="jobRepository" />
</bean>

<import resource="classpath:spring-batch1.xml" />
       <!-- configure spring scheduler -->
<task:annotation-driven />
<task:scheduled-tasks>
<task:scheduled ref="launch1" method="runIt" cron="0/5 * * * * *"></task:scheduled>
<task:scheduled ref="launch2" method="runIt" cron="0/8 * * * * *"></task:scheduled>
</task:scheduled-tasks>
</beans>


in order to store sprint batch meta data, need to create tables provided by spring framework, which can be found in spring-batch-core-<version>.RELEASE.jar, they are schema-drop-mysql.sql and schema-mysql.sql

take note, some indexes need to be added in database manually, refer to B.10 at http://docs.spring.io/spring-batch/2.2.x/reference/html/metaDataSchema.html

2) spring batch configuration file spring-batch1.xml

<beans:beans xmlns="http://www.springframework.org/schema/batch"
xmlns:beans="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.2.xsd">

<job id="batch1" job-repository="jobRepository" restartable="true">
<step id="step1">
<tasklet ref="helloTasklet" />
</step>
</job>

<job id="batch2" job-repository="jobRepository" restartable="true">
<step id="step2">
<tasklet ref="helloTasklet2" />
</step>
</job>

</beans:beans>


3) java code to launch job batch1

package wx.batch1;

import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.JobParametersBuilder;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

@Service("launch1")
public class Launch1 {

@Autowired
@Qualifier("jobLauncher")
private JobLauncher jobLauncher;
@Autowired
@Qualifier("batch1")
private Job job;

public void runIt() {
JobParameters jobParameters = new JobParametersBuilder().addLong(
"time", System.currentTimeMillis()).toJobParameters();
try {
JobExecution execution = jobLauncher.run(job, jobParameters);
} catch (Exception e) {

e.printStackTrace();
}
}

public JobLauncher getJobLauncher() {
return jobLauncher;
}

public void setJobLauncher(JobLauncher jobLauncher) {
this.jobLauncher = jobLauncher;
}

public Job getJob() {
return job;
}

public void setJob(Job job) {
this.job = job;
}

}

4) tasklet for job batch1

package wx.batch1;

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;
import org.springframework.stereotype.Service;

@Service("helloTasklet")
public class HelloWorldTasklet implements Tasklet {

public RepeatStatus execute(StepContribution arg0, ChunkContext arg1)
throws Exception {
System.out.println("Hello World " + new java.util.Date());
return RepeatStatus.FINISHED;
}

}


5) java code to launch job batch2

package wx.batch1;

import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.JobParametersBuilder;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

@Service("launch2")
public class Launch2 {

@Autowired
@Qualifier("jobLauncher")
private JobLauncher jobLauncher;
@Autowired
@Qualifier("batch2")
private Job job;

public void runIt() {
JobParameters jobParameters = new JobParametersBuilder().addLong(
"time", System.currentTimeMillis()).toJobParameters();
try {
JobExecution execution = jobLauncher.run(job, jobParameters);
} catch (Exception e) {

e.printStackTrace();
}
}

public JobLauncher getJobLauncher() {
return jobLauncher;
}

public void setJobLauncher(JobLauncher jobLauncher) {
this.jobLauncher = jobLauncher;
}

public Job getJob() {
return job;
}

public void setJob(Job job) {
this.job = job;
}

}


6) tasklet for batch2

package wx.batch1;

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;
import org.springframework.stereotype.Service;

@Service("helloTasklet2")
public class HelloWorldTasklet2 implements Tasklet {

public RepeatStatus execute(StepContribution arg0, ChunkContext arg1)
throws Exception {
System.out.println("Hello World22222 " + new java.util.Date());
return RepeatStatus.FINISHED;
}

}


7) launch class

package wx.batch1;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class LaunchScheduler {

public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
"app-context.xml");
context.start();
}

}

No comments:

Post a Comment