Add customizer for conversion service used by Spring Batch

See gh-34769
This commit is contained in:
Claudio Nave 2023-03-26 17:02:28 +02:00 committed by Andy Wilkinson
parent 60eb01bcaa
commit cafa6f5d9c
3 changed files with 102 additions and 2 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@ -16,6 +16,8 @@
package org.springframework.boot.autoconfigure.batch;
import java.util.List;
import javax.sql.DataSource;
import org.springframework.batch.core.configuration.ListableJobLocator;
@ -44,6 +46,7 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.core.convert.support.ConfigurableConversionService;
import org.springframework.jdbc.datasource.init.DatabasePopulator;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.Isolation;
@ -115,11 +118,15 @@ public class BatchAutoConfiguration {
private final BatchProperties properties;
private final List<BatchConversionServiceCustomizer> batchConversionServiceCustomizers;
SpringBootBatchConfiguration(DataSource dataSource, @BatchDataSource ObjectProvider<DataSource> batchDataSource,
PlatformTransactionManager transactionManager, BatchProperties properties) {
PlatformTransactionManager transactionManager, BatchProperties properties,
List<BatchConversionServiceCustomizer> batchConversionServiceCustomizers) {
this.dataSource = batchDataSource.getIfAvailable(() -> dataSource);
this.transactionManager = transactionManager;
this.properties = properties;
this.batchConversionServiceCustomizers = batchConversionServiceCustomizers;
}
@Override
@ -144,6 +151,15 @@ public class BatchAutoConfiguration {
return (isolation != null) ? isolation : super.getIsolationLevelForCreate();
}
@Override
protected ConfigurableConversionService getConversionService() {
ConfigurableConversionService conversionService = super.getConversionService();
for (BatchConversionServiceCustomizer customizer : this.batchConversionServiceCustomizers) {
customizer.customize(conversionService);
}
return conversionService;
}
}
@Configuration(proxyBeanMethods = false)

View File

@ -0,0 +1,39 @@
/*
* Copyright 2023 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.autoconfigure.batch;
import org.springframework.core.convert.support.ConfigurableConversionService;
/**
* Callback interface that can be implemented by beans wishing to further customize the
* {@link ConfigurableConversionService} used in
* {@link org.springframework.batch.core.configuration.support.DefaultBatchConfiguration}
* retaining its default auto-configuration.
*
* @author Claudio Nave
* @since 3.1.0
*/
@FunctionalInterface
public interface BatchConversionServiceCustomizer {
/**
* Customize the {@link ConfigurableConversionService}.
* @param configurableConversionService the ConfigurableConversionService to customize
*/
void customize(ConfigurableConversionService configurableConversionService);
}

View File

@ -71,6 +71,8 @@ import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.convert.converter.Converter;
import org.springframework.core.convert.support.ConfigurableConversionService;
import org.springframework.jdbc.BadSqlGrammarException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
@ -400,6 +402,21 @@ class BatchAutoConfigurationTests {
.hasBean("customInitializer"));
}
@Test
void userProvidedCustomConverter() {
this.contextRunner.withUserConfiguration(TestConfiguration.class, EmbeddedDataSourceConfiguration.class)
.withUserConfiguration(RegisterCustomConverter.class)
.run((context) -> {
assertThat(context).hasSingleBean(SpringBootBatchConfiguration.class);
ConfigurableConversionService configurableConversionService = context
.getBean(SpringBootBatchConfiguration.class)
.getConversionService();
assertThat(configurableConversionService.canConvert(RegisterCustomConverter.Foo.class,
RegisterCustomConverter.Bar.class))
.isTrue();
});
}
@Configuration(proxyBeanMethods = false)
protected static class BatchDataSourceConfiguration {
@ -680,4 +697,32 @@ class BatchAutoConfigurationTests {
}
@Configuration(proxyBeanMethods = false)
static class RegisterCustomConverter {
@Bean
BatchConversionServiceCustomizer batchConversionServiceCustomizer() {
return (configurableConversionService) -> configurableConversionService
.addConverter(new FooToBarConverter());
}
static class Foo {
}
static class Bar {
}
static class FooToBarConverter implements Converter<Foo, Bar> {
@Override
public Bar convert(Foo source) {
return null;
}
}
}
}