执行spring批处理以运行后台进程

时间:2015-03-23 07:25:22

标签: spring spring-mvc parallel-processing spring-batch

我正在尝试实施春季批次,但我几乎没有问题。请在下面找到我的代码。

spring-dispatcher-servlet.xml(我正在添加我作为spring批次的一部分添加的内容)

<!--  Spring Batch implementation starts --> 

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

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

<bean id="simpleJob" class="org.springframework.batch.core.job.SimpleJob" abstract="true">
    <property name="jobRepository" ref="jobRepository" />
</bean>
<!-- Spring Batch implementation ends  -->

弹簧batch.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:util="http://www.springframework.org/schema/util" 
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 xsi:schemaLocation="http://www.springframework.org/schema/batch 
 http://www.springframework.org/schema/batch/spring-batch-2.2.xsd 
 http://www.springframework.org/schema/beans 
 http://www.springframework.org/schema/beans/spring-beans-3.2.xsd 
 http://www.springframework.org/schema/util http://www.springframework.org  /schema/util/spring-util-3.2.xsd">

   <import resource="classpath:spring-dispatcher-servlet.xml"/>

 <bean id="customReader" class="com.batchjob.CustomItemReader" >
    <property name="userId" value="#{jobParameters['userId']}" > </property>
</bean>



     <bean id="customProcessor" class="com.batchjob.CustomItemProcessor" />

    <bean id="customWriter" class="com.batchjob.CustomItemWriter" />   

  <bean id="simpleStep" class="org.springframework.batch.core.step.item.SimpleStepFactoryBean">
    <property name="transactionManager" ref="transactionManager" />
    <property name="jobRepository" ref="jobRepository" />

    <property name="itemReader" ref="customReader"/>
    <property name="itemProcessor" ref="customProcessor"/>
    <property name="itemWriter" ref="customWriter"/>

    <property name="commitInterval" value="2" />
</bean>

<bean id="readerWriterJob" parent="simpleJob">
    <property name="steps">
        <list>
            <ref bean="simpleStep"/>
        </list>
    </property>
</bean>

CustomItemReader.java

 package com.batchjob;

import java.sql.ResultSet;  
import java.sql.SQLException;

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.beans.factory.annotation.Autowired;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
 import com.beans.UserLogin;



 public class CustomItemReader implements ItemReader<UserLogin> {

 @Autowired
 private JdbcTemplate jdbcTemplate;
 private String username;
  @Override
  public UserLogin read() throws Exception, UnexpectedInputException,
        ParseException, NonTransientResourceException {

    System.out.println("In DaoImpl of user login");
    String sql = "select * from USERS where user_name=? ";
    try {
        return (UserLogin) jdbcTemplate.queryForObject(sql,
                new Object[] { (username) }, new RowMapper<UserLogin>() {
                    @Override
                    public UserLogin mapRow(ResultSet rs, int rowNum)
                            throws SQLException {
                        UserLogin userLoginDetails = new UserLogin();
                        userLoginDetails.setUserName(rs
                                .getString("user_name"));
                        userLoginDetails.setPassword(rs
                                .getString("user_password"));
                        userLoginDetails.setRole(rs.getString("user_role"));
                        userLoginDetails.setFullName(rs
                                .getString("user_fullname"));
                        return userLoginDetails;
                    }
                });
    } catch (EmptyResultDataAccessException e) {
        return null;
    }

   }
   }

CustomItemProcessor.java

 package com.batchjob;

import org.springframework.batch.item.ItemProcessor;

public class CustomItemProcessor implements ItemProcessor<Object, Object> {

@Override
public Object process(Object arg0) throws Exception {


    // how to get all the values that customItemReader have fetched from the table ?


    // perform some more activity

    return null;
 }

 }

CustomItemWriter.java

package com.batchjob;

import java.util.List;

import org.springframework.batch.item.ItemWriter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;

import com.bean.UserLogin;

public class CustomItemWriter implements ItemWriter<UserLogin> {
@Autowired
private JdbcTemplate jdbcTemplate;
UserLogin userloginObj;
String status="Success";

@Override
public void write(List arg0) throws Exception {

userloginObj.setStatus(status);
String sql = "update table_name set status=?";

        try {

            jdbcTemplate.update(sql,
                    new Object[] { userloginObj.getStatus()});

        }

        catch (Exception ex) {
            ex.printStackTrace();
        }
    }
  }

控制器代码:

     public void addUserDetails(@RequestParam("name") String username,
        @RequestParam("fullname") String fullname,
        @RequestParam("role") String role,
        @RequestParam("loginPassword") String loginPassword,
        @RequestParam("userStatus") String userStatus  ) {

    try {

        adduser.setUserName(username);
        adduser.setFullName(fullname);
        adduser.setLoginPassword(loginPassword);
        adduser.setUserStatus(userStatus);
        adduser.setRole(role);

        userLoginDAOImpl.insertAddUserDetails(adduser);


      here i have to run the job that i don'nt know how to run it. like this i am doing in my demo code. (Here also if i write a function to invoke this job that should run in background)



  String[] springConfig = { "batch-job.xml" };

  @SuppressWarnings("resource")
   ApplicationContext context = new ClassPathXmlApplicationContext(springConfig);

 JobLauncher jobLauncher = (JobLauncher) context.getBean("jobLauncher");
 Job job = (Job) context.getBean("testJob");

 try {

    JobParameters param = new JobParametersBuilder().addString("age", "20").toJobParameters();

    JobExecution execution = jobLauncher.run(job, param);
    System.out.println("Exit Status : " + execution.getStatus());
    System.out.println("Exit Status : " + execution.getAllFailureExceptions());

    } catch (Exception e) {
    e.printStackTrace();
  }
   System.out.println("Done");

    } catch (Exception ex) {
        ex.printStackTrace();

     }
   }

现在我有2个问题 Q.1如何在我的控制器中运行这个作业,以便satatment应该在后台运行我的意思是下面应该开始执行,他们不应该等待上面的语句完成。

Q2。我写的ItemReader,预处理器和itemWriter代码我不确定它是否正确可以任何人验证它吗?

1 个答案:

答案 0 :(得分:1)

选项1

您可以使用SimpleAsyncTaskExecutor配置弹出批处理,并且可以调用将在后台运行的弹出批处理作业执行(因此您将有一些活动 - &gt;在后台触发作业执行 - &gt;执行其他活动) ,像:

@Bean
public JobLauncher jobLauncher() {
    final SimpleJobLauncher jobLauncher = new SimpleJobLauncher();
    jobLauncher.setJobRepository(jobRepository);
    final SimpleAsyncTaskExecutor simpleAsyncTaskExecutor = new SimpleAsyncTaskExecutor();
    jobLauncher.setTaskExecutor(simpleAsyncTaskExecutor);
    return jobLauncher;
}

选项2

正如你所说,你可以在DB中保存参数,但是spring批处理具有保存状态等所有基础设施。我建议不要重新发明轮子,而是使用spring scheduling mechanism检查DB表中的新参数,如果它们是有ItemReader的实现之一启动作业,它从DB读取,在结果中进行处理和写入者更新DB。

以下是Spring batch samples on github的链接,这是一个很好的起点,有很多例子。