Можно создать пакетное задание как @Component, используя внедренный JobBuilderFactory в этот компонент

Мне любопытно, можно ли определить 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 03.07.2019 23:46

Не мог бы ваш @Morfic посмотреть код, который я отправляю?

Sebastian 04.07.2019 06:29

Этот случай не работает и не может работать, но я не знаю, как создать экземпляр задания с помощью JobBuilderFactory, пока мне пришла в голову идея создать задание с помощью @PostCostruct и установить все необходимые объекты для ImportEmployeeJob всеми возможными способами. метод setters со значением задания, возвращаемым из построителя. Но после работы проверю. Может быть, у вас есть другая лучшая идея?

Sebastian 04.07.2019 10:04
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
3
360
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Для этого можно использовать заводской бин. Вот краткий пример:

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-компонента в конструктор или сеттеры вместо ввода поля?

Sebastian 04.07.2019 18:09

Здорово. Рад помочь! В этом случае примите ответ (см. stackoverflow.com/help/someone-answers). Что касается внедрения зависимостей, я бы рекомендовал внедрение конструктора для обязательных зависимостей и внедрение установщика для необязательных зависимостей (внедрение поля не рекомендуется). Я обновил ответ с помощью инъекции конструктора.

Mahmoud Ben Hassine 04.07.2019 18:38

Я спрашиваю о внедрении конструктора, потому что в этом случае Spring выдает исключение, что bean-компоненту нужен конструктор по умолчанию. Таким образом, DI с помощью конструктора с введенными bean-компонентами в качестве исключения параметра. Я думаю, что возможна только инъекция сеттерами, но этого достаточно, чтобы сделать класс легко тестируемым. Извините, но у меня недостаточно очков репутации, чтобы проголосовать за ответ. В любом случае еще раз спасибо :)

Sebastian 04.07.2019 18:48

Другие вопросы по теме