280 likes | 1.02k Views
Spring-Batch Tutorial. Guide for Application Developers. Agenda. “Hello world!” job Simple job – programming a Tasklet directly Common job – weaving standard components Sample jobs. “Hello World!” - tasklet. public class HelloWorldTasklet implements Tasklet {
E N D
Spring-Batch Tutorial Guide for Application Developers
Agenda • “Hello world!” job • Simple job – programming a Tasklet directly • Common job – weaving standard components • Sample jobs
“Hello World!” - tasklet publicclass HelloWorldTasklet implements Tasklet { public ExitStatus execute() throws Exception { System.out.println("Hello world!"); return ExitStatus.FINISHED; } }
“Hello World!” - tasklet publicclass HelloWorldTasklet implements Tasklet { public ExitStatus execute() throws Exception { System.out.println("Hello world!"); return ExitStatus.FINISHED; } }
“Hello World!” - configuration <bean id="jobConfiguration" parent="simpleJob"> <property name="name" value="helloWorldJob" /> <property name="steps"> <list> <bean id="step1" parent="simpleStep"> <constructor-arg> <bean class="...HelloWorldTasklet" /> </constructor-arg> </bean> </list> </property> </bean>
“Hello World!” - configuration <bean id="jobConfiguration" parent="simpleJob"> <property name="name" value="helloWorldJob" /> <property name="steps"> <list> <bean id="step1" parent="simpleStep"> <constructor-arg> <bean class="...HelloWorldTasklet" /> </constructor-arg> </bean> </list> </property> </bean>
Simple job - tasklet publicclass SimpleTasklet implements Tasklet { private InputSource inputSource; private OutputSource outputSource; public ExitStatus execute() throws Exception { Object data = inputSource.read(); if (data != null) { outputSource.write(data); return ExitStatus.CONTINUABLE; } return ExitStatus.FINISHED; } publicvoid setInputSource(InputSource inputSource) { this.inputSource = inputSource; } publicvoid setOutputSource(OutputSource outputSource) { this.outputSource = outputSource; } }
Simple job - tasklet publicclass SimpleTasklet implements Tasklet { private InputSource inputSource; private OutputSource outputSource; public ExitStatus execute() throws Exception { Object data = inputSource.read(); if (data != null) { outputSource.write(data); return ExitStatus.CONTINUABLE; } return ExitStatus.FINISHED; } publicvoid setInputSource(InputSource inputSource) { this.inputSource = inputSource; } publicvoid setOutputSource(OutputSource outputSource) { this.outputSource = outputSource; } }
Simple job - tasklet publicclass SimpleTasklet implements Tasklet { private InputSource inputSource; private OutputSource outputSource; public ExitStatus execute() throws Exception { Object data = inputSource.read(); if (data != null) { outputSource.write(data); return ExitStatus.CONTINUABLE; } return ExitStatus.FINISHED; } publicvoid setInputSource(InputSource inputSource) { this.inputSource = inputSource; } publicvoid setOutputSource(OutputSource outputSource) { this.outputSource = outputSource; } }
Simple job - configuration <bean id="jobConfiguration" parent="simpleJob"> <property name="name" value="simpleTaskletJob" /> <property name="steps"> <list> <bean id="step1" parent="simpleStep"> <constructor-arg> <bean class="...SimpleTasklet"> <property name="inputSource" ref="inputSource" /> <property name="outputSource" ref="outputSource" /> </bean> </constructor-arg> </bean> </list> </property> </bean>
Simple job – input source <bean id=“inputSource"class="...SqlCursorInputSource“ scope="step" > <aop:scoped-proxy /> <property name="dataSource" ref="dataSource" /> <property name="sql" value="SELECT id, quantity, price, customer from TRADE" /> <property name="mapper"> <bean class="...TradeRowMapper" /> </property> </bean>
Simple job – input source <bean id=“inputSource"class="...SqlCursorInputSource“ scope="step" > <aop:scoped-proxy /> <constructor-arg> <ref bean="dataSource" /> </constructor-arg> <property name="sql" value="SELECT id, quantity, price, customer from TRADE" /> <property name="mapper"> <bean class="...TradeRowMapper" /> </property> </bean>
Simple job – output source <bean id="outputSource" class="...FlatFileOutputSource“ scope="step" > <aop:scoped-proxy /> <property name="resource" value="file:out.txt" /> </bean>
Common job - configuration <bean id="jobConfiguration" parent="simpleJob"> <property name="name" value="commonJob" /> <property name="steps"> <bean id="step1" parent="simpleStep"> <constructor-arg> <beanclass="...tasklet.RestartableItemProviderTasklet"> <property name="itemProvider"> <beanclass="...tasklet.support.InputSourceItemProvider"> <property name="source" ref="sqlInputSource" /> </bean> </property> <property name="itemProcessor"> <bean class="...tasklet.support.OutputSourceItemProcessor"> <property name="source" ref="xmlOutputSource" /> </bean> </property> </bean> </constructor-arg> </bean> </property> </bean>
Common job – tasklet <beanclass="...tasklet.RestartableItemProviderTasklet"> <property name="itemProvider"> <beanclass="...tasklet.support.InputSourceItemProvider"> <property name="source" ref="sqlInputSource" /> </bean> </property> <property name="itemProcessor"> <bean class="...tasklet.support.OutputSourceItemProcessor"> <property name="source" ref="xmlOutputSource" /> </bean> </property> </bean>
Common job – tasklet <beanclass="...tasklet.RestartableItemProviderTasklet"> <property name="itemProvider"> <beanclass="...tasklet.support.InputSourceItemProvider"> <property name="source" ref="sqlInputSource" /> </bean> </property> <property name="itemProcessor"> <bean class="...tasklet.support.OutputSourceItemProcessor"> <property name="source" ref="xmlOutputSource" /> </bean> </property> </bean>
Common job – tasklet <beanclass="...tasklet.RestartableItemProviderTasklet"> <property name="itemProvider"> <beanclass="...tasklet.support.InputSourceItemProvider"> <property name="source" ref="sqlInputSource" /> </bean> </property> <property name="itemProcessor"> <bean class="...tasklet.support.OutputSourceItemProcessor"> <property name="source" ref="xmlOutputSource" /> </bean> </property> </bean>
Samples overview • Samples project contains simple batch jobs illustrating various capabilities of the Spring-Batch framework • See the folder src/main/resources/jobs for job configuration files • See src/test/java, package org.springframework.batch.sample for tests which launch the jobs and check the expected results
simpleTaskletJob.xml • Straightforwardly implemented Tasklet, similar to the “Simple Job” example • All-in-one solution to help understand tasklet’s execution logic • Standard solutions are more modular, which makes them more flexible and reusable, but also less straightforward to understand
fixedLengthImportJob.xml • Clean separation of reading input and processing data (standard from now on) • Typical scenario of importing data from a fixed-length file to database • Custom DAO used for output
multilineOrderJob.xml • Handling of complex file format, both reading input and writing output • Single record spans multiple lines and has nested records • Custom ItemProvider and ItemProcessor implementations handling non-standard file format
tradeJob.xml • shows a reasonably complex scenario, that would resemble the real-life usage of the framework • 3 steps: • trade records are imported from file to database • customer account balance is adjusted • report about customers is exported to a file
compositeProcessorSample.xml • Parallel writing to multiple outputs • Example usage of composite ItemProcessor with an injected list of ItemProcessors
restartSample.xml • Simulates restart scenario, where the job crashes on first run and succeeds after being restarted • Uses ‘hacked’ tasklet that throws exception after reading a given number of records