Мне любопытно, можно ли определить Spring Batch Job иначе, чем методом создания bean-компонента. Есть ли способ определить пакетное задание, создав @Component, который расширяет задание, и используя введенный JobBuilderFactory для создания экземпляра, чтобы избежать реализации всего необходимого метода вручную?
@Component
public class ImportEmployeeJob extends FlowJob {
private final JobBuilderFactory jobBuilderFactory;
private final FlowStep printProcessedEmployeeFromCsv;
public ImportEmployeeJob(JobBuilderFactory jobBuilderFactory, FlowStep printProcessedEmployeeFromCsv, ApplicationContext context) {
this.jobBuilderFactory = jobBuilderFactory;
this.printProcessedEmployeeFromCsv = printProcessedEmployeeFromCsv;
jobBuilderFactory.get("importEmployeeJob")
.incrementer(new RunIdIncrementer())
.listener(new PersonCsvJobExecutionListener())
.flow(printProcessedEmployeeFromCsv)
.end()
.build();
}
}
Это немного глупый пример, но я просто хочу показать вам, что я имею в виду
Не мог бы ваш @Morfic посмотреть код, который я отправляю?
Этот случай не работает и не может работать, но я не знаю, как создать экземпляр задания с помощью JobBuilderFactory, пока мне пришла в голову идея создать задание с помощью @PostCostruct и установить все необходимые объекты для ImportEmployeeJob всеми возможными способами. метод setters со значением задания, возвращаемым из построителя. Но после работы проверю. Может быть, у вас есть другая лучшая идея?




Для этого можно использовать заводской бин. Вот краткий пример:
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.Step;
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.beans.factory.FactoryBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
@Configuration
@EnableBatchProcessing
public class MyJob {
public static void main(String[] args) throws Exception {
ApplicationContext context = new AnnotationConfigApplicationContext(MyJob.class);
JobLauncher jobLauncher = context.getBean(JobLauncher.class);
Job job = context.getBean(Job.class);
jobLauncher.run(job, new JobParameters());
}
@Component
public static class MyJobFactoryBean implements FactoryBean<Job> {
private final JobBuilderFactory jobs;
private final StepBuilderFactory steps;
public MyJobFactoryBean(JobBuilderFactory jobs, StepBuilderFactory steps) {
this.jobs = jobs;
this.steps = steps;
}
@Override
public Job getObject() {
Step step = steps.get("step")
.tasklet((contribution, chunkContext) -> {
System.out.println("hello world");
return RepeatStatus.FINISHED;
})
.build();
return jobs.get("job")
.start(step)
.build();
}
@Override
public Class<?> getObjectType() {
return Job.class;
}
@Override
public boolean isSingleton() {
return true;
}
}
}
Надеюсь, поможет.
Да работа спасибо. Есть ли обходной путь для внедрения bean-компонента в конструктор или сеттеры вместо ввода поля?
Здорово. Рад помочь! В этом случае примите ответ (см. stackoverflow.com/help/someone-answers). Что касается внедрения зависимостей, я бы рекомендовал внедрение конструктора для обязательных зависимостей и внедрение установщика для необязательных зависимостей (внедрение поля не рекомендуется). Я обновил ответ с помощью инъекции конструктора.
Я спрашиваю о внедрении конструктора, потому что в этом случае Spring выдает исключение, что bean-компоненту нужен конструктор по умолчанию. Таким образом, DI с помощью конструктора с введенными bean-компонентами в качестве исключения параметра. Я думаю, что возможна только инъекция сеттерами, но этого достаточно, чтобы сделать класс легко тестируемым. Извините, но у меня недостаточно очков репутации, чтобы проголосовать за ответ. В любом случае еще раз спасибо :)
Не могли бы вы быть более конкретным? Как выглядит ваш код до сих пор, и в чем ваша проблема с ним?