TechFind
TechFind

Reputation: 3696

Spring batch with Annotation

I am new to Spring batch, looking for some example developed Spring batch with Annotation concept.

This link (click) talks about Spring batch, but not Spring batch with annotation concept. As discussed in given link documentation is not clear. I am using latest Spring framework. I want to avoid xml configuration.

Is Spring batch is very good tool for batch processing? or Is there any better tools available for batch processing instead of Spring batch?

Is there any limitations in Spring batch?

Upvotes: 6

Views: 22029

Answers (7)

Ramnath
Ramnath

Reputation: 11

I have a experience of creating and maintaining the spring batch applications from scratch. Annotations based configuration is preferred over XML based configuration for many reasons.

Spring batch is well suited for processing records or transactions in bulk because of the performance and the features it provides.

Most of the readers and writers are available built-in which will reduce your work. For example reading and writing into CSV files, reading and writing into the database. And it will give multiple task executors, partitioners for multi threading and parallel processing. You will also be able to trace the issues or monitor the application using different JobExecution and StepExecution listeners and methods which are there to be performed after and before read or write operation in batch. Like AfterRead, BeforeRead, AfterStep etc.

Performance-wise too good for read, process and write operations.

Go for it. Thanks for the question.

Upvotes: 0

HaMi
HaMi

Reputation: 539

I've worked with Spring Batch for about 2.5 years and I will suggest you to use xml files for configuration of your jobs not annotations. Of course you can use annotations for so many configurations, like step and job definition, job launcher and job repository definition, tasklet and listeners, deciders and so many other necessary components. But unfortunately I've found it so hard to connect components together specially when you are forced to use partitioners. You can gain profits with annotations in case of debugging but it will be much more easier to track your job's flow in case of xml cause you have all your configurations in one xml file (and maybe more files if you like to make it more readable).

Upvotes: 1

Nikhil Pareek
Nikhil Pareek

Reputation: 764

I faced the same problem when I was reading about Spring batch Annotations. The best place where you can read about Spring annotations is the reference documentation. The concepts are the same for batch, whether or not XML or Java is used.

I would suggest following these steps:

  • Study about the batch concepts
  • Try to make simple batch applications (reading from a database and saving to CSV)
  • Once confortable with basic concepts, study from books like Spring Batch Pro.
  • If you encounter a problem, look online for code and then cross-reference that with the aforementioned Spring documentation.

Upvotes: 0

darkled
darkled

Reputation: 257

Please take a look at my tutorial together with the github repo, maybe it will be useful for you.

Spring Batch as any other tool has its own limitation but still is quite flexible. I'm using it in a real project with 1500 different jobs running and I think it's pretty good and covers a lot of use cases in the batch processing applications.

Upvotes: 0

Manohar Kokkula
Manohar Kokkula

Reputation: 61

I used following technologies for this example : Spring batch 3.0.5.RELEASE,

JDK 1.7,

Eclipse Mars Release (4.5.0),

Maven 3.3.3,

Springframework 4.0.5.ReLEASE.

Step 1: Create simple POJO, Employee.java

public class Employee {

private  String name;
private  String empId;
public String getName() {
    return name;
}
public void setName(String name) {
    this.name = name;
}
public String getEmpId() {
    return empId;
}
public void setEmpId(String empId) {
    this.empId = empId;
}
@Override
public String toString() {
    return "Employee [name=" + name + ", empId=" + empId + "]";
}
}

Step 2: Create java class, ClassReader.java

package com.batch.main;

import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.NonTransientResourceException;
import org.springframework.batch.item.ParseException;
import org.springframework.batch.item.UnexpectedInputException;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import com.batch.beans.Employee;

@Component("classReader")
public class ClassReader implements ItemReader<Employee> {

@Override
public Employee read() throws Exception, UnexpectedInputException,           ParseException, NonTransientResourceException {

    Employee emp=new Employee();
    //Set values in Employee object
    emp.setEmpId("123456");
    emp.setName("Manohar");
    System.out.println("Inside ClassReader..." + emp);
    return emp;
}

}

Step 3: Create java class, ClassProcessor.java

package com.batch.main;

import org.springframework.batch.item.ItemProcessor;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import com.batch.beans.Employee;

@Component("classProcesser")
public class ClassProcessor  implements ItemProcessor<Employee, Employee>{

@Override
public Employee process(Employee emp) throws Exception {
    System.out.println("Inside ClassProcessor..." + emp);
    return emp;
}

}

Step 4: Create java class, ClassWriter.java

package com.batch.main;

import java.util.List;
import org.springframework.batch.item.ItemWriter;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import com.batch.beans.Employee;

@Component("classWriter")
public class ClassWriter implements ItemWriter<Employee> {

@Override
public void write(List<? extends Employee> arg0) throws Exception {

    System.out.println("Inside ClassWriter..." + arg0);

}

}

Step 5: Create context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:tx="http://www.springframework.org/schema/tx"                xmlns:context="http://www.springframework.org/schema/context"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"    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-3.0.xsd
http://www.springframework.org/schema/tx   http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/context  http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/jdbc  http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd">

<bean id="transactionManager"
class="org.springframework.batch.support.transaction.
ResourcelessTransactionMana ger" />

<bean id="jobRepository"
class="org.springframework.batch.core.repository.support.
MapJobRepositoryFactoryBean">
<property name="transactionManager" ref="transactionManager" />
</bean>

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


</beans>

Step 6: Create job.xml

<?xml version="1.0" encoding="UTF-8"?>
<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:task="http://www.springframework.org/schema/task"     xmlns:tx="http://www.springframework.org/schema/tx"
 xmlns:context="http://www.springframework.org/schema/context"
 xmlns:util="http://www.springframework.org/schema/util"     xmlns:crypt="http://springcryptoutils.com/schema/crypt"
 xsi:schemaLocation="
 http://www.springframework.org/schema/beans     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
 http://www.springframework.org/schema/batch     http://www.springframework.org/schema/batch/spring-batch-3.0.xsd
 http://www.springframework.org/schema/tx     http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
 http://www.springframework.org/schema/context     http://www.springframework.org/schema/context/spring-context-3.0.xsd
 http://www.springframework.org/schema/util     http://www.springframework.org/schema/util/spring-util-3.0.xsd
 http://springcryptoutils.com/schema/crypt     http://springcryptoutils.com/schema/crypt.xsd
 http://www.springframework.org/schema/task     http://www.springframework.org/schema/task/spring-task-3.2.xsd">

<import resource="/context.xml" />

<context:component-scan base-package="com.batch" />

<batch:job id="loadJob" xmlns="http://www.springframework.org/schema/batch">
  <batch:step id="step1" >
    <batch:tasklet>
     <batch:chunk reader="classReader" writer="classWriter"
     processor="classProcesser" commit-interval="1" />
    </batch:tasklet>
  </batch:step>
</batch:job>

<!-- <bean id="classReader" class="com.batch.main.ClassReader" >

</bean>

<bean id="classWriter" class="com.batch.main.ClassWriter" ></bean>

<bean id="classProcesser" class="com.batch.main.ClassProcessor" > </bean>-->

Step 7: Finally create Main.java

package com.batch.main;

import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
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.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;


@Configuration
@ImportResource({"classpath:/com/spring/job/job.xml"})//load configuration       file from classpath
 public class Main {

 public static void main(String[] args) throws              JobExecutionAlreadyRunningException, 
JobRestartException,         
JobInstanceAlreadyCompleteException, JobParametersInvalidException {
@SuppressWarnings("resource")
AnnotationConfigApplicationContext context = new             AnnotationConfigApplicationContext();
     context.register(Main.class);
     context.refresh();
     //load jobLauncher details from context.xml file
      JobLauncher jobLauncher = (JobLauncher) context.getBean("jobLauncher");
      //load Job details from job.xml file
       Job job = (Job) context.getBean("loadJob");
       //run job
       JobExecution execution = jobLauncher.run(job, new JobParameters());
       System.out.println("Exit Status : " + execution.getStatus());
         }
}

Now Run above program as Java application, you will see the output on console.

Please refer http://manohark.com/simple-spring-batch-example-using-annotations/ for complete details.

Upvotes: 0

MTLam
MTLam

Reputation: 11

Have you look at http://www.joshlong.com/jl/blogPost/java_configuration_with_spring_batch.html

If you defined all the necessary "bean" object, in the main method, you can just get them in the application context.

ApplicationContext ctx = new AnnotationConfigApplicationContext(MainConfig.class);
job = (Job) ctx.getBean("SOME JOB");
jobLauncher = (JobLauncher) ctx.getBean("jobLauncher");
jobLauncher.run(job, jobParams);

Upvotes: 1

dma_k
dma_k

Reputation: 10649

Spring batch supports only limited functionality which you can configure using annotations. Mainly these are listener callbacks, like @BeforeStep or @AfterChunk. Using these annotations provides you a choice either to implement corresponding interfaces or to use annotated methods. Annotated bean has to be injected into job, step or chunk (reader, processor, writer, retry-policy, skip-policy or listeners) in XML configuration, which you cannot avoid.

Upvotes: 2

Related Questions