实现春季批处理运行后台流程



我正在尝试实现spring-batch,但我有一些问题。请在我的代码下面找到。

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

<!--  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  -->

Spring-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();
     }
   }

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

Q2.我写的ItemReader、预处理器和itemWriter代码我不确定它是否正确,有人能验证吗?

选项1

您可以使用SimpleAsyncTaskExecutor配置spring-batch,然后可以调用将在后台运行的spring-batchjob执行(因此您将有一些活动->在后台触发job执行->执行其他活动),类似于:

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

选项2

正如你所说,你可以将参数保存在数据库中,但spring-batch拥有保存状态等的所有基础设施。我建议不要重新发明轮子,而是使用spring-scheduling机制来检查数据库表中的新参数,如果有ItemReader的一个实现,它可以从数据库中读取、进行处理并在结果中更新数据库。

下面是github上Spring批处理示例的链接,这是一个很好的起点,有很多示例。

最新更新