将作业配置导入普通作业配置class(注解配置)

Import job configurations into common job configuration class (Annotation config)

我正在重构基于 Spring 批处理 XML 的遗留应用程序以改为使用注释配置。我想了解如何将以下 XML 文件转换为基于注释的配置并保持相同的关注点分离。

为了便于讨论,这里举个简单的例子。

作业配置-1.xml

<job id="job1" xmlns="http://www.springframework.org/schema/batch">
               <batch:step id="step1">
                    <batch:tasklet throttle-limit="20" task-executor="taskExecutor">
                        <batch:chunk reader="reader1"
                            writer="writer1" commit-interval="500" />
                    </batch:tasklet>
                </batch:step>
</job>

作业配置-2.xml

<job id="job2" xmlns="http://www.springframework.org/schema/batch">
                   <batch:step id="step2">
                        <batch:tasklet throttle-limit="20" task-executor="taskExecutor">
                            <batch:chunk reader="reader2"
                                writer="writer2" commit-interval="500" />
                        </batch:tasklet>
                    </batch:step>
</job>

作业配置-3.xml

<import
        resource="classpath*:/spring/jobs/job-config-1.xml" />
<import
        resource="classpath*:/spring/jobs/job-config-2.xml" />
<batch:job id="jobFlow">

            
    <batch:step id="step1" next="step2">
        <job ref="job1" job-launcher="jobLauncher" />
    </batch:step>

    <batch:step id="step2">
        <job ref="job2" job-launcher="jobLauncher" />
    </batch:step>
    
</batch:job>

我想从 XML 配置移动到 Java 配置。我想为每个 XML 创建 3 个作业配置 类。比方说 JobConfig1.java、JobConfig2.java 和 JobConfig3.java.

JobConfig3.java 将导入 JobConfig1.java 和 JobConfig2.java;但是,我无法在文档中找到这种结构的示例。我该怎么做?

注意:我不想使用 Spring Boot。只是常规Spring通过注解配置批量

您可以使用 JobStep 来定义您的步骤,例如在您的 Job3step1 应该如下所示:

@Autowired
ApplicationContext context;

public Step step1() {
    return stepBuilderFactory.get("step1").job(context.getBean("job1", Job.class))
            .parametersExtractor(new DefaultJobParametersExtractor()).build();
}

由此,您可以 运行 step1 像任何其他步骤一样,但是当 job3 将上诉此步骤时,将执行 job1 的所有步骤。 job1 是您的主体 job3 的子工作。

对于job1他的定义应该是这样的:(和JobConfig2一样)

@Configuration
class JobConfig1 {

    @Autowired
    private JobBuilderFactory jobBuilderFactory;

    @Autowired
    private StepBuilderFactory stepBuilderFactory;

    @Bean
    public Job job1() {
        return jobBuilderFactory.get("job1").incrementer(new RunIdIncrementer()).start(step1()).build();
    }

    // definition of steps
    public Step step1() {
        return null;
    }
}

与您的 XML 配置等效的是在其自己的配置 class 中定义每个作业,然后将这些 class 导入主作业的配置中。这是一个简单的例子:

import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

@Configuration
// @Import({Job1Config.class, Job2Config.class}) // use this if the classes where you define sub jobs are not nested
@EnableBatchProcessing
public class MainJobConfig {

    @Bean
    public Job mainJob(JobBuilderFactory jobs, StepBuilderFactory steps, Job job1, Job job2, JobLauncher jobLauncher) {
        return jobs.get("mainJob")
                .start(steps.get("subJob1").job(job1).launcher(jobLauncher).build())
                .next(steps.get("subJob2").job(job2).launcher(jobLauncher).build())
                .build();
    }
    
    @Configuration
    static class Job1Config {
        // define job 1 artefacts (reader, writer, steps, etc)
        // for simplicity, the step is inlined in the job definition
        @Bean
        public Job job1(JobBuilderFactory jobs, StepBuilderFactory steps) {
            return jobs.get("job1")
                    .start(steps.get("job1Step1").tasklet((contribution, chunkContext) -> {
                        System.out.println("job1");
                        return RepeatStatus.FINISHED;
                    }).build())
                    .build();
        }
    }

    @Configuration
    static class Job2Config {
        // define job 2 artefacts (reader, writer, steps, etc)
        // for simplicity, the step is inlined in the job definition
        @Bean
        public Job job2(JobBuilderFactory jobs, StepBuilderFactory steps) {
            return jobs.get("job2")
                    .start(steps.get("job2Step1").tasklet((contribution, chunkContext) -> {
                        System.out.println("job2");
                        return RepeatStatus.FINISHED;
                    }).build())
                    .build();
        }
    }

    public static void main(String[] args) throws Exception {
        ApplicationContext context = new AnnotationConfigApplicationContext(MainJobConfig.class);
        JobLauncher jobLauncher = context.getBean(JobLauncher.class);
        Job job = context.getBean("mainJob", Job.class);
        jobLauncher.run(job, new JobParameters());
    }

}