adding java based spring batch configuration

This commit is contained in:
Devendra Desale 2015-12-13 22:12:09 +08:00
parent 9b2b856661
commit 57b27f6c9c
9 changed files with 376 additions and 195 deletions

View File

@ -1,45 +1,44 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>org.baeldung</groupId> <groupId>org.baeldung</groupId>
<artifactId>spring-batch-intro</artifactId> <artifactId>spring-batch-intro</artifactId>
<version>0.1-SNAPSHOT</version> <version>0.1-SNAPSHOT</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<name>spring-batch-intro</name> <name>spring-batch-intro</name>
<url>http://maven.apache.org</url> <url>http://maven.apache.org</url>
<properties> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring.version>4.0.2.RELEASE</spring.version> <spring.version>4.2.0.RELEASE</spring.version>
<spring.batch.version>3.0.5.RELEASE</spring.batch.version> <spring.batch.version>3.0.5.RELEASE</spring.batch.version>
<sqlite.version>3.8.11.2</sqlite.version> <sqlite.version>3.8.11.2</sqlite.version>
</properties> </properties>
<dependencies> <dependencies>
<!-- SQLite database driver --> <!-- SQLite database driver -->
<dependency> <dependency>
<groupId>org.xerial</groupId> <groupId>org.xerial</groupId>
<artifactId>sqlite-jdbc</artifactId> <artifactId>sqlite-jdbc</artifactId>
<version>${sqlite.version}</version> <version>${sqlite.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.springframework</groupId> <groupId>org.springframework</groupId>
<artifactId>spring-oxm</artifactId> <artifactId>spring-oxm</artifactId>
<version>${spring.version}</version> <version>${spring.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.springframework</groupId> <groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId> <artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version> <version>${spring.version}</version>
</dependency> </dependency>
<dependency>
<dependency> <groupId>org.springframework.batch</groupId>
<groupId>org.springframework.batch</groupId> <artifactId>spring-batch-core</artifactId>
<artifactId>spring-batch-core</artifactId> <version>${spring.batch.version}</version>
<version>${spring.batch.version}</version> </dependency>
</dependency> </dependencies>
</dependencies>
</project> </project>

View File

@ -1,28 +1,38 @@
package org.baeldung.spring_batch_intro; package org.baeldung.spring_batch_intro;
import javax.swing.Spring;
import org.springframework.batch.core.Job; import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution; import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobParameters; import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.launch.JobLauncher; import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;
public class App { public class App {
public static void main(String[] args) { public static void main(String[] args) {
// Spring Java config
AnnotationConfigApplicationContext context = new
AnnotationConfigApplicationContext();
context.register(SpringConfig.class);
context.register(SpringBatchConfig.class);
context.refresh();
ApplicationContext context = new ClassPathXmlApplicationContext( // Spring xml config
"/spring-batch-intro.xml"); // ApplicationContext context = new ClassPathXmlApplicationContext(
// "spring-batch-intro.xml");
JobLauncher jobLauncher = (JobLauncher) context.getBean("jobLauncher");
Job job = (Job) context.getBean("firstBatchJob"); JobLauncher jobLauncher = (JobLauncher) context.getBean("jobLauncher");
System.out.println("Starting the batch job"); Job job = (Job) context.getBean("firstBatchJob");
try { System.out.println("Starting the batch job");
JobExecution execution = jobLauncher.run(job, new JobParameters()); try {
System.out.println("Job Status : " + execution.getStatus()); JobExecution execution = jobLauncher.run(job, new JobParameters());
System.out.println("Job completed"); System.out.println("Job Status : " + execution.getStatus());
} catch (Exception e) { System.out.println("Job completed");
e.printStackTrace(); } catch (Exception e) {
System.out.println("Job failed"); e.printStackTrace();
} System.out.println("Job failed");
} }
}
} }

View File

@ -0,0 +1,92 @@
package org.baeldung.spring_batch_intro;
import java.net.MalformedURLException;
import java.text.ParseException;
import org.baeldung.spring_batch_intro.model.Transaction;
import org.baeldung.spring_batch_intro.service.CustomItemProcessor;
import org.baeldung.spring_batch_intro.service.RecordFieldSetMapper;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.item.ItemProcessor;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.UnexpectedInputException;
import org.springframework.batch.item.file.FlatFileItemReader;
import org.springframework.batch.item.file.mapping.DefaultLineMapper;
import org.springframework.batch.item.file.transform.DelimitedLineTokenizer;
import org.springframework.batch.item.xml.StaxEventItemWriter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.core.io.Resource;
import org.springframework.oxm.Marshaller;
import org.springframework.oxm.jaxb.Jaxb2Marshaller;
public class SpringBatchConfig {
@Autowired
private JobBuilderFactory jobs;
@Autowired
private StepBuilderFactory steps;
@Value("input/record.csv")
private Resource inputCsv;
@Value("file:xml/output.xml")
private Resource outputXml;
@Bean
public ItemReader<Transaction> itemReader()
throws UnexpectedInputException, ParseException, Exception {
FlatFileItemReader<Transaction> reader = new FlatFileItemReader<Transaction>();
DelimitedLineTokenizer tokenizer = new DelimitedLineTokenizer();
String[] tokens = { "username", "userid", "transactiondate", "amount" };
tokenizer.setNames(tokens);
reader.setResource(inputCsv);
DefaultLineMapper<Transaction> lineMapper = new DefaultLineMapper<Transaction>();
lineMapper.setLineTokenizer(tokenizer);
lineMapper.setFieldSetMapper(new RecordFieldSetMapper());
reader.setLineMapper(lineMapper);
return reader;
}
@Bean
public ItemProcessor<Transaction, Transaction> itemProcessor() {
return new CustomItemProcessor();
}
@Bean
public ItemWriter<Transaction> itemWriter(Marshaller marshaller)
throws MalformedURLException {
StaxEventItemWriter<Transaction> itemWriter = new StaxEventItemWriter<Transaction>();
itemWriter.setMarshaller(marshaller);
itemWriter.setRootTagName("transactionRecord");
itemWriter.setResource(outputXml);
return itemWriter;
}
@Bean
public Marshaller marshaller() {
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setClassesToBeBound(new Class[] { Transaction.class });
return marshaller;
}
@Bean
protected Step step1(ItemReader<Transaction> reader,
ItemProcessor<Transaction, Transaction> processor,
ItemWriter<Transaction> writer) {
return steps.get("step1").<Transaction, Transaction> chunk(10)
.reader(reader).processor(processor).writer(writer).build();
}
@Bean(name = "firstBatchJob")
public Job job(@Qualifier("step1") Step step1) {
return jobs.get("firstBatchJob").start(step1).build();
}
}

View File

@ -0,0 +1,75 @@
package org.baeldung.spring_batch_intro;
import java.net.MalformedURLException;
import javax.sql.DataSource;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.core.launch.support.SimpleJobLauncher;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.repository.support.JobRepositoryFactoryBean;
import org.springframework.batch.support.transaction.ResourcelessTransactionManager;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.jdbc.datasource.init.DataSourceInitializer;
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
import org.springframework.transaction.PlatformTransactionManager;
@Configuration
@EnableBatchProcessing
public class SpringConfig {
@Value("org/springframework/batch/core/schema-drop-sqlite.sql")
private Resource dropReopsitoryTables;
@Value("org/springframework/batch/core/schema-sqlite.sql")
private Resource dataReopsitorySchema;
@Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("org.sqlite.JDBC");
dataSource.setUrl("jdbc:sqlite:repository.sqlite");
return dataSource;
}
@Bean
public DataSourceInitializer dataSourceInitializer(DataSource dataSource)
throws MalformedURLException {
ResourceDatabasePopulator databasePopulator = new ResourceDatabasePopulator();
databasePopulator.addScript(dropReopsitoryTables);
databasePopulator.addScript(dataReopsitorySchema);
databasePopulator.setIgnoreFailedDrops(true);
DataSourceInitializer initializer = new DataSourceInitializer();
initializer.setDataSource(dataSource);
initializer.setDatabasePopulator(databasePopulator);
return initializer;
}
private JobRepository getJobRepository() throws Exception {
JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean();
factory.setDataSource(dataSource());
factory.setTransactionManager(getTransactionManager());
factory.afterPropertiesSet();
return (JobRepository) factory.getObject();
}
private PlatformTransactionManager getTransactionManager() {
return new ResourcelessTransactionManager();
}
public JobLauncher getJobLauncher() throws Exception {
SimpleJobLauncher jobLauncher = new SimpleJobLauncher();
jobLauncher.setJobRepository(getJobRepository());
jobLauncher.afterPropertiesSet();
return jobLauncher;
}
}

View File

@ -7,48 +7,48 @@ import javax.xml.bind.annotation.XmlRootElement;
@SuppressWarnings("restriction") @SuppressWarnings("restriction")
@XmlRootElement(name = "transactionRecord") @XmlRootElement(name = "transactionRecord")
public class Transaction { public class Transaction {
private String username; private String username;
private int userId; private int userId;
private Date transactionDate; private Date transactionDate;
private double amount; private double amount;
public String getUsername() { public String getUsername() {
return username; return username;
} }
public void setUsername(String username) { public void setUsername(String username) {
this.username = username; this.username = username;
} }
public int getUserId() { public int getUserId() {
return userId; return userId;
} }
public void setUserId(int userId) { public void setUserId(int userId) {
this.userId = userId; this.userId = userId;
} }
public Date getTransactionDate() { public Date getTransactionDate() {
return transactionDate; return transactionDate;
} }
public void setTransactionDate(Date transactionDate) { public void setTransactionDate(Date transactionDate) {
this.transactionDate = transactionDate; this.transactionDate = transactionDate;
} }
public double getAmount() { public double getAmount() {
return amount; return amount;
} }
public void setAmount(double amount) { public void setAmount(double amount) {
this.amount = amount; this.amount = amount;
} }
@Override @Override
public String toString() { public String toString() {
return "Transaction [username=" + username + ", userId=" + userId return "Transaction [username=" + username + ", userId=" + userId
+ ", transactionDate=" + transactionDate + ", amount=" + amount + ", transactionDate=" + transactionDate + ", amount=" + amount
+ "]"; + "]";
} }
} }

View File

@ -1,14 +1,13 @@
package org.baeldung.spring_batch_intro.service; package org.baeldung.spring_batch_intro.service;
import org.baeldung.spring_batch_intro.model.Transaction; import org.baeldung.spring_batch_intro.model.Transaction;
import org.springframework.batch.item.ItemProcessor; import org.springframework.batch.item.ItemProcessor;
public class CustomItemProcessor implements ItemProcessor<Transaction, Transaction> { public class CustomItemProcessor implements
ItemProcessor<Transaction, Transaction> {
public Transaction process(Transaction item) throws Exception { public Transaction process(Transaction item) throws Exception {
System.out.println("Processing..." + item);
System.out.println("Processing..." + item); return item;
return item; }
}
} }

View File

@ -10,24 +10,24 @@ import org.springframework.validation.BindException;
public class RecordFieldSetMapper implements FieldSetMapper<Transaction> { public class RecordFieldSetMapper implements FieldSetMapper<Transaction> {
public Transaction mapFieldSet(FieldSet fieldSet) throws BindException { public Transaction mapFieldSet(FieldSet fieldSet) throws BindException {
SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
Transaction transaction = new Transaction();
transaction.setUsername(fieldSet.readString("username"));
transaction.setUserId(fieldSet.readInt(1));
transaction.setAmount(fieldSet.readDouble(3));
//Converting the date
String dateString = fieldSet.readString(2);
try {
transaction.setTransactionDate(dateFormat.parse(dateString));
} catch (ParseException e) {
e.printStackTrace();
}
return transaction; SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
Transaction transaction = new Transaction();
} transaction.setUsername(fieldSet.readString("username"));
transaction.setUserId(fieldSet.readInt(1));
transaction.setAmount(fieldSet.readDouble(3));
// Converting the date
String dateString = fieldSet.readString(2);
try {
transaction.setTransactionDate(dateFormat.parse(dateString));
} catch (ParseException e) {
e.printStackTrace();
}
return transaction;
}
} }

View File

@ -1,61 +1,66 @@
<beans xmlns="http://www.springframework.org/schema/beans" <beans xmlns="http://www.springframework.org/schema/beans"
xmlns:batch="http://www.springframework.org/schema/batch" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:batch="http://www.springframework.org/schema/batch" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/batch xsi:schemaLocation="http://www.springframework.org/schema/batch
http://www.springframework.org/schema/batch/spring-batch-3.0.xsd http://www.springframework.org/schema/batch/spring-batch-3.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
"> ">
<import resource="spring.xml" /> <import resource="spring.xml" />
<bean id="record" class="org.baeldung.spring_batch_intro.model.Transaction"></bean>
<bean id="itemReader" class="org.springframework.batch.item.file.FlatFileItemReader">
<property name="resource" value="input/record.csv" /> <bean id="record" class="org.baeldung.spring_batch_intro.model.Transaction"></bean>
<property name="lineMapper"> <bean id="itemReader"
<bean class="org.springframework.batch.item.file.mapping.DefaultLineMapper"> class="org.springframework.batch.item.file.FlatFileItemReader">
<property name="lineTokenizer">
<bean
class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer">
<property name="names" value="username,userid,transactiondate,amount" />
</bean>
</property>
<property name="fieldSetMapper">
<bean
class="org.baeldung.spring_batch_intro.service.RecordFieldSetMapper" />
</property> <property name="resource" value="input/record.csv" />
</bean>
</property>
</bean>
<bean id="itemProcessor"
class="org.baeldung.spring_batch_intro.service.CustomItemProcessor" />
<bean id="itemWriter" class="org.springframework.batch.item.xml.StaxEventItemWriter">
<property name="resource" value="file:xml/output.xml" />
<property name="marshaller" ref="recordMarshaller" />
<property name="rootTagName" value="transactionRecord" />
</bean>
<bean id="recordMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller"> <property name="lineMapper">
<property name="classesToBeBound"> <bean
<list> class="org.springframework.batch.item.file.mapping.DefaultLineMapper">
<value>org.baeldung.spring_batch_intro.model.Transaction</value> <property name="lineTokenizer">
</list> <bean
</property> class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer">
</bean> <property name="names"
value="username,userid,transactiondate,amount" />
</bean>
</property>
<property name="fieldSetMapper">
<bean
class="org.baeldung.spring_batch_intro.service.RecordFieldSetMapper" />
</property>
<batch:job id="firstBatchJob"> </bean>
<batch:step id="step1"> </property>
<batch:tasklet> </bean>
<batch:chunk reader="itemReader" writer="itemWriter"
processor="itemProcessor" commit-interval="10"> <bean id="itemProcessor"
</batch:chunk> class="org.baeldung.spring_batch_intro.service.CustomItemProcessor" />
</batch:tasklet>
</batch:step> <bean id="itemWriter"
</batch:job> class="org.springframework.batch.item.xml.StaxEventItemWriter">
<property name="resource" value="file:xml/output.xml" />
<property name="marshaller" ref="recordMarshaller" />
<property name="rootTagName" value="transactionRecord" />
</bean>
<bean id="recordMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="classesToBeBound">
<list>
<value>org.baeldung.spring_batch_intro.model.Transaction
</value>
</list>
</property>
</bean>
<batch:job id="firstBatchJob">
<batch:step id="step1">
<batch:tasklet>
<batch:chunk reader="itemReader" writer="itemWriter"
processor="itemProcessor" commit-interval="10">
</batch:chunk>
</batch:tasklet>
</batch:step>
</batch:job>
</beans> </beans>

View File

@ -1,44 +1,45 @@
<beans xmlns="http://www.springframework.org/schema/beans" <beans xmlns="http://www.springframework.org/schema/beans"
xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=" xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc
http://www.springframework.org/schema/jdbc/spring-jdbc-4.0.xsd"> http://www.springframework.org/schema/jdbc/spring-jdbc-4.2.xsd">
<!-- connect to SQLite database --> <!-- connect to SQLite database -->
<bean id="dataSource" <bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource"> class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.sqlite.JDBC" /> <property name="driverClassName" value="org.sqlite.JDBC" />
<property name="url" value="jdbc:sqlite:repository.sqlite" /> <property name="url" value="jdbc:sqlite:repository.sqlite" />
<property name="username" value="" /> <property name="username" value="" />
<property name="password" value="" /> <property name="password" value="" />
</bean> </bean>
<!-- create job-meta tables automatically --> <!-- create job-meta tables automatically -->
<jdbc:initialize-database data-source="dataSource"> <jdbc:initialize-database data-source="dataSource">
<jdbc:script location="org/springframework/batch/core/schema-drop-sqlite.sql" /> <jdbc:script
<jdbc:script location="org/springframework/batch/core/schema-sqlite.sql" /> location="org/springframework/batch/core/schema-drop-sqlite.sql" />
</jdbc:initialize-database> <jdbc:script location="org/springframework/batch/core/schema-sqlite.sql" />
</jdbc:initialize-database>
<!-- stored job-meta in memory --> <!-- stored job-meta in memory -->
<!-- <bean id="jobRepository" class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean"> <!-- <bean id="jobRepository" class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean">
<property name="transactionManager" ref="transactionManager" /> </bean> --> <property name="transactionManager" ref="transactionManager" /> </bean> -->
<!-- stored job-meta in database --> <!-- stored job-meta in database -->
<bean id="jobRepository" <bean id="jobRepository"
class="org.springframework.batch.core.repository.support.JobRepositoryFactoryBean"> class="org.springframework.batch.core.repository.support.JobRepositoryFactoryBean">
<property name="dataSource" ref="dataSource" /> <property name="dataSource" ref="dataSource" />
<property name="transactionManager" ref="transactionManager" /> <property name="transactionManager" ref="transactionManager" />
<property name="databaseType" value="sqlite" /> <property name="databaseType" value="sqlite" />
</bean> </bean>
<bean id="transactionManager" <bean id="transactionManager"
class="org.springframework.batch.support.transaction.ResourcelessTransactionManager" /> class="org.springframework.batch.support.transaction.ResourcelessTransactionManager" />
<bean id="jobLauncher" <bean id="jobLauncher"
class="org.springframework.batch.core.launch.support.SimpleJobLauncher"> class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
<property name="jobRepository" ref="jobRepository" /> <property name="jobRepository" ref="jobRepository" />
</bean> </bean>
</beans> </beans>