Resolves Circular Dependency issue

Makes sure that dependencies are passed in via parameters in bean declaraction vs. Autowiring

refer to https://github.com/spring-projects/spring-batch/issues/3991
resolves #797

Updated based on code review
This commit is contained in:
Glenn Renfro
2021-09-07 17:24:40 -04:00
parent 8b4352095d
commit 332e693d5e
5 changed files with 30 additions and 79 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2019-2020 the original author or authors.
* Copyright 2019-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -41,6 +41,7 @@ import org.springframework.context.annotation.Configuration;
* Autconfiguration for a {@code FlatFileItemReader}.
*
* @author Michael Minella
* @author Glenn Renfro
* @since 2.3
*/
@Configuration
@@ -50,21 +51,6 @@ public class FlatFileItemReaderAutoConfiguration {
private final FlatFileItemReaderProperties properties;
@Autowired(required = false)
private LineTokenizer lineTokenizer;
@Autowired(required = false)
private FieldSetMapper<Map<String, Object>> fieldSetMapper;
@Autowired(required = false)
private LineMapper<Map<String, Object>> lineMapper;
@Autowired(required = false)
private LineCallbackHandler skippedLinesCallback;
@Autowired(required = false)
private RecordSeparatorPolicy recordSeparatorPolicy;
public FlatFileItemReaderAutoConfiguration(FlatFileItemReaderProperties properties) {
this.properties = properties;
}
@@ -72,7 +58,12 @@ public class FlatFileItemReaderAutoConfiguration {
@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(prefix = "spring.batch.job.flatfileitemreader", name = "name")
public FlatFileItemReader<Map<String, Object>> itemReader() {
public FlatFileItemReader<Map<String, Object>> itemReader(
@Autowired(required = false) LineTokenizer lineTokenizer,
@Autowired(required = false) FieldSetMapper<Map<String, Object>> fieldSetMapper,
@Autowired(required = false) LineMapper<Map<String, Object>> lineMapper,
@Autowired(required = false) LineCallbackHandler skippedLinesCallback,
@Autowired(required = false) RecordSeparatorPolicy recordSeparatorPolicy) {
FlatFileItemReaderBuilder<Map<String, Object>> mapFlatFileItemReaderBuilder = new FlatFileItemReaderBuilder<Map<String, Object>>()
.name(this.properties.getName()).resource(this.properties.getResource())
.saveState(this.properties.isSaveState())
@@ -84,26 +75,14 @@ public class FlatFileItemReaderAutoConfiguration {
.comments(this.properties.getComments()
.toArray(new String[this.properties.getComments().size()]));
if (this.lineTokenizer != null) {
mapFlatFileItemReaderBuilder.lineTokenizer(this.lineTokenizer);
}
if (this.recordSeparatorPolicy != null) {
mapFlatFileItemReaderBuilder.lineTokenizer(lineTokenizer);
if (recordSeparatorPolicy != null) {
mapFlatFileItemReaderBuilder
.recordSeparatorPolicy(this.recordSeparatorPolicy);
}
if (this.fieldSetMapper != null) {
mapFlatFileItemReaderBuilder.fieldSetMapper(this.fieldSetMapper);
}
if (this.lineMapper != null) {
mapFlatFileItemReaderBuilder.lineMapper(this.lineMapper);
}
if (this.skippedLinesCallback != null) {
mapFlatFileItemReaderBuilder.skippedLinesCallback(skippedLinesCallback);
.recordSeparatorPolicy(recordSeparatorPolicy);
}
mapFlatFileItemReaderBuilder.fieldSetMapper(fieldSetMapper);
mapFlatFileItemReaderBuilder.lineMapper(lineMapper);
mapFlatFileItemReaderBuilder.skippedLinesCallback(skippedLinesCallback);
if (this.properties.isDelimited()) {
mapFlatFileItemReaderBuilder.delimited()

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2020-2020 the original author or authors.
* Copyright 2020-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -38,6 +38,7 @@ import org.springframework.jdbc.core.RowMapper;
/**
* @author Michael Minella
* @author Glenn Renfro
* @since 2.3
*/
@Configuration
@@ -50,12 +51,6 @@ public class JdbcCursorItemReaderAutoConfiguration {
private final DataSource dataSource;
@Autowired(required = false)
private PreparedStatementSetter preparedStatementSetter;
@Autowired(required = false)
private RowMapper<Map<String, Object>> rowMapper;
public JdbcCursorItemReaderAutoConfiguration(
JdbcCursorItemReaderProperties properties, DataSource dataSource) {
this.properties = properties;
@@ -64,7 +59,8 @@ public class JdbcCursorItemReaderAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public JdbcCursorItemReader<Map<String, Object>> itemReader() {
public JdbcCursorItemReader<Map<String, Object>> itemReader(@Autowired(required = false) RowMapper<Map<String, Object>> rowMapper,
@Autowired(required = false) PreparedStatementSetter preparedStatementSetter) {
return new JdbcCursorItemReaderBuilder<Map<String, Object>>()
.name(this.properties.getName())
.currentItemCount(this.properties.getCurrentItemCount())
@@ -76,8 +72,8 @@ public class JdbcCursorItemReaderAutoConfiguration {
.maxRows(this.properties.getMaxRows())
.queryTimeout(this.properties.getQueryTimeout())
.saveState(this.properties.isSaveState()).sql(this.properties.getSql())
.rowMapper(this.rowMapper)
.preparedStatementSetter(this.preparedStatementSetter)
.rowMapper(rowMapper)
.preparedStatementSetter(preparedStatementSetter)
.verifyCursorPosition(this.properties.isVerifyCursorPosition())
.useSharedExtendedConnection(
this.properties.isUseSharedExtendedConnection())

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2020-2020 the original author or authors.
* Copyright 2020-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -27,11 +27,8 @@ import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
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.explore.JobExplorer;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.item.file.FlatFileItemReader;
import org.springframework.batch.item.file.LineCallbackHandler;
import org.springframework.batch.item.file.LineMapper;
import org.springframework.batch.item.file.mapping.FieldSetMapper;
@@ -39,7 +36,6 @@ import org.springframework.batch.item.file.separator.RecordSeparatorPolicy;
import org.springframework.batch.item.file.transform.DefaultFieldSet;
import org.springframework.batch.item.file.transform.LineTokenizer;
import org.springframework.batch.item.support.ListItemWriter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration;
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
@@ -53,6 +49,7 @@ import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Michael Minella
* @author Glenn Renfro
*/
public class FlatFileItemReaderAutoConfigurationTests {
@@ -319,15 +316,6 @@ public class FlatFileItemReaderAutoConfigurationTests {
@Configuration
public static class CustomMappingConfiguration {
@Autowired
private JobBuilderFactory jobBuilderFactory;
@Autowired
private StepBuilderFactory stepBuilderFactory;
@Autowired
private FlatFileItemReader itemReader;
@Bean
public ListItemWriter<Map<String, Object>> itemWriter() {
return new ListItemWriter<>();

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2018-2019 the original author or authors.
* Copyright 2018-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -28,7 +28,6 @@ import org.springframework.batch.core.configuration.annotation.EnableBatchProces
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.cloud.task.batch.configuration.TaskBatchTest;
import org.springframework.cloud.task.configuration.EnableTask;
@@ -39,7 +38,7 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
/**
* @author Glenn Renfro
@@ -73,15 +72,9 @@ public class PrefixTests {
@EnableTask
public static class JobConfiguration {
@Autowired
private JobBuilderFactory jobBuilderFactory;
@Autowired
private StepBuilderFactory stepBuilderFactory;
@Bean
public Job job() {
return this.jobBuilderFactory.get("job").start(this.stepBuilderFactory
public Job job(JobBuilderFactory jobBuilderFactory, StepBuilderFactory stepBuilderFactory) {
return jobBuilderFactory.get("job").start(stepBuilderFactory
.get("step1").tasklet((contribution, chunkContext) -> {
System.out.println("Executed");
return RepeatStatus.FINISHED;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016-2019 the original author or authors.
* Copyright 2016-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -361,16 +361,11 @@ public class TaskBatchExecutionListenerTests {
@Import(EmbeddedDataSourceConfiguration.class)
public static class JobConfigurationMultipleDataSources {
@Autowired
private JobBuilderFactory jobBuilderFactory;
@Autowired
private StepBuilderFactory stepBuilderFactory;
@Bean
public Job job() {
return this.jobBuilderFactory.get("job")
.start(this.stepBuilderFactory.get("step1").tasklet(new Tasklet() {
public Job job(JobBuilderFactory jobBuilderFactory, StepBuilderFactory stepBuilderFactory) {
return jobBuilderFactory.get("job")
.start(stepBuilderFactory.get("step1").tasklet(new Tasklet() {
@Override
public RepeatStatus execute(StepContribution contribution,
ChunkContext chunkContext) throws Exception {