Pol Hernández
Pol Hernández

Reputation: 11

Using custom TaskExecutor in Spring Batch

I want to set a Sync/Async TaskExecutor in Spring Batch. Is that possible?

I want to configure my step as follows:

<job id="myJob" xmlns="http://www.springframework.org/schema/batch">
    <step id="step1">
        <tasklet task-executor="MyTaskExecutor">
            <chunk reader="ReaderFile" processor="ProcessFile" writer="WriterFile"
                commit-interval="10" />
        </tasklet>
    </step>
</job>

Then create the bean "MyTaskExecutor" as follows:

<bean id="MyTaskExecutor" scope="step" class="batch.app.util.MyTaskExecutor"/>

Then in my class configure the TaskExecutor. (Now working as Async):

package batch.app.util;
import org.springframework.batch.core.JobExecution;
import org.springframework.core.task.TaskExecutor;

public class MyTaskExecutor extends SimpleAsyncTaskExecutor{

    public TaskExecutor taskExecutor(){

        return new SimpleAsyncTaskExecutor("spring_batch");
    }

}

I would like that MyTaskExecutor extends from wether SimpleAsyncTaskExecutor or SyncTaskExecutor depending on a condition... Or if that is not possible, to be Async but before executing the step, check that condition and if the taskExecutor executing that step, then throw an error.

I've been looking if there is a way to obtain the class of the TaskExecutor from the Reader (or the Processor or the Writer), but didn't find anything.

Thank you very much

Upvotes: 1

Views: 8393

Answers (1)

Vignesh T I
Vignesh T I

Reputation: 872

You can use a condition inside your job config to pick up the custom task executor. Below is a small snippet with an annotation driven bean creation for reference. You can use similar logic in your configuration approach as well.

Below has a condition on the TaskExecutor which can be resolved at the time of construction and we can create custom executors and add it up to the step config,

Job job = jobBuilderFactory.get("testJob").incrementer(new RunIdIncrementer())
               .start(testStep()).next(testStep1()).end()
               .listener(jobCompletionListener()).build();

@Bean
public Step testStep() {

    boolean sync = false;

    AbstractTaskletStepBuilder<SimpleStepBuilder<String, Test>> stepConfig = stepBuilderFactory
            .get("testStep").<String, Test>chunk(10)
            .reader(reader())
            .processor(processor())
            .writer(writer())
            .listener(testListener());

    if (sync) {
        stepConfig.taskExecutor(syncTaskExecutor());
    } else {
        stepConfig.taskExecutor(asyncTaskExecutor());
    }

    return stepConfig.build();
}

@Bean
public TaskExecutor asyncTaskExecutor() {
    SimpleAsyncTaskExecutor taskExecutor = new SimpleAsyncTaskExecutor();
    taskExecutor.setConcurrencyLimit(10);
    return taskExecutor;
}

// Similarly, other TaskExecutor can have its own bean config

Upvotes: 4

Related Questions