diff --git a/annotations/src/main/java/org/mapstruct/extensions/spring/SpringMapperConfig.java b/annotations/src/main/java/org/mapstruct/extensions/spring/SpringMapperConfig.java index 40107ac..1e5e1a1 100644 --- a/annotations/src/main/java/org/mapstruct/extensions/spring/SpringMapperConfig.java +++ b/annotations/src/main/java/org/mapstruct/extensions/spring/SpringMapperConfig.java @@ -14,6 +14,20 @@ @Target(ElementType.TYPE) @Retention(RetentionPolicy.SOURCE) public @interface SpringMapperConfig { + + String DEFAULT_CONVERSION_SERVICE_BEAN_NAME = "conversionService"; + String DEFAULT_ADAPTER_CLASS_NAME = "ConversionServiceAdapter"; + String DEFAULT_CONFIGURATION_CLASS_NAME = "ConverterRegistrationConfiguration"; + + /** + * The class name for the generated Configuration class, + * which is performing auto-registration of converters/mappers + * to Spring's {@link org.springframework.core.convert.ConversionService}. + * + * @return The class name for the generated Configuration. + */ + String converterRegistrationConfigurationClassName() default DEFAULT_CONFIGURATION_CLASS_NAME; + /** * The package name for the generated Adapter between the MapStruct mappers and Spring's {@link * org.springframework.core.convert.ConversionService}. If omitted or empty, the package name will @@ -29,7 +43,7 @@ * * @return The class name for the generated Adapter. */ - String conversionServiceAdapterClassName() default "ConversionServiceAdapter"; + String conversionServiceAdapterClassName() default DEFAULT_ADAPTER_CLASS_NAME; /** * The bean name for the Spring {@link org.springframework.core.convert.ConversionService} to use. @@ -37,7 +51,7 @@ * @return The bean name for the Spring {@link * org.springframework.core.convert.ConversionService}. */ - String conversionServiceBeanName() default ""; + String conversionServiceBeanName() default DEFAULT_CONVERSION_SERVICE_BEAN_NAME; /** * To set if the Lazy annotation will be added to the ConversionService's usage in the diff --git a/docs/src/docs/asciidoc/chapter-3-mapper-as-converter.asciidoc b/docs/src/docs/asciidoc/chapter-3-mapper-as-converter.asciidoc index 2fe63a0..e998a70 100644 --- a/docs/src/docs/asciidoc/chapter-3-mapper-as-converter.asciidoc +++ b/docs/src/docs/asciidoc/chapter-3-mapper-as-converter.asciidoc @@ -170,6 +170,70 @@ public class ConversionServiceAdapterIntegrationTest { ---- ==== +[[converterRegistrationConfigurationClassName]] +=== Modifying the name for the generated converter registration configuration class + +By default, the converter registration configuration class will have name `ConverterRegistrationConfiguration`. +If you wish to change this, you can do so by setting the property `converterRegistrationConfigurationClassName`: + +==== +[source,java,linenums] +[subs="verbatim,attributes"] +---- +@MapperConfig(componentModel = "spring") +@SpringMapperConfig( + converterRegistrationConfigurationClassName = "MyConfiguration", + generateConverterScan = true) +public interface MapstructConfig {} +---- +==== + +This changes the generated class name to be the property's value: + +==== +[source,java,linenums] +[subs="verbatim,attributes"] +---- +@Configuration +class MyConfiguration { + private final ConfigurableConversionService conversionService; + + private final List> converters; + + MyConfiguration( + @Qualifier("conversionService") final ConfigurableConversionService conversionService, + final List> converters) { + this.conversionService = conversionService; + this.converters = converters; + } + + @PostConstruct + void registerConverters() { + converters.forEach(conversionService::addConverter); + } +} +---- +==== + +Also this changes reference to converter registration configuration class from generated ConverterScan class: + +==== +[source,java,linenums] +[subs="verbatim,attributes"] +---- +@ComponentScan +@Target(TYPE) +@Import(MyConfiguration.class) +@Documented +@Retention(RUNTIME) +@Repeatable(ConverterScans.class) +public @interface ConverterScan { + ... +} +---- +==== + + [[adapterMethodName]] === Modifying the name for the generated adapter method diff --git a/examples/custom-converter-registration-configuration-with-converter-scan/build.gradle b/examples/custom-converter-registration-configuration-with-converter-scan/build.gradle new file mode 100644 index 0000000..53734ad --- /dev/null +++ b/examples/custom-converter-registration-configuration-with-converter-scan/build.gradle @@ -0,0 +1,14 @@ +dependencies { + annotationProcessor project(":extensions") + implementation projects.examples.model + implementation projects.annotations + + testImplementation libs.assertj + testImplementation libs.bundles.junit.jupiter + implementation libs.jsr250 + implementation libs.mapstruct.core + annotationProcessor libs.mapstruct.processor + implementation libs.spring.context + implementation libs.spring.core + testImplementation libs.spring.test +} diff --git a/examples/custom-converter-registration-configuration-with-converter-scan/src/main/java/org/mapstruct/extensions/spring/example/customconfiguration/CarMapper.java b/examples/custom-converter-registration-configuration-with-converter-scan/src/main/java/org/mapstruct/extensions/spring/example/customconfiguration/CarMapper.java new file mode 100644 index 0000000..66224ec --- /dev/null +++ b/examples/custom-converter-registration-configuration-with-converter-scan/src/main/java/org/mapstruct/extensions/spring/example/customconfiguration/CarMapper.java @@ -0,0 +1,13 @@ +package org.mapstruct.extensions.spring.example.customconfiguration; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.springframework.core.convert.converter.Converter; +import org.mapstruct.extensions.spring.example.Car; +import org.mapstruct.extensions.spring.example.CarDto; + +@Mapper(config = MapperSpringConfig.class) +public interface CarMapper extends Converter { + @Mapping(target = "seats", source = "seatConfiguration") + CarDto convert(Car car); +} diff --git a/examples/custom-converter-registration-configuration-with-converter-scan/src/main/java/org/mapstruct/extensions/spring/example/customconfiguration/MapperSpringConfig.java b/examples/custom-converter-registration-configuration-with-converter-scan/src/main/java/org/mapstruct/extensions/spring/example/customconfiguration/MapperSpringConfig.java new file mode 100644 index 0000000..82e8c88 --- /dev/null +++ b/examples/custom-converter-registration-configuration-with-converter-scan/src/main/java/org/mapstruct/extensions/spring/example/customconfiguration/MapperSpringConfig.java @@ -0,0 +1,11 @@ +package org.mapstruct.extensions.spring.example.customconfiguration; + +import org.mapstruct.MapperConfig; +import org.mapstruct.extensions.spring.SpringMapperConfig; + +@MapperConfig(componentModel = "spring", uses = ConversionServiceAdapter.class) +@SpringMapperConfig( + converterRegistrationConfigurationClassName = "MyConfiguration", + generateConverterScan = true) +public interface MapperSpringConfig { +} diff --git a/examples/custom-converter-registration-configuration-with-converter-scan/src/main/java/org/mapstruct/extensions/spring/example/customconfiguration/SeatConfigurationMapper.java b/examples/custom-converter-registration-configuration-with-converter-scan/src/main/java/org/mapstruct/extensions/spring/example/customconfiguration/SeatConfigurationMapper.java new file mode 100644 index 0000000..2ac6369 --- /dev/null +++ b/examples/custom-converter-registration-configuration-with-converter-scan/src/main/java/org/mapstruct/extensions/spring/example/customconfiguration/SeatConfigurationMapper.java @@ -0,0 +1,14 @@ +package org.mapstruct.extensions.spring.example.customconfiguration; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.extensions.spring.example.SeatConfiguration; +import org.mapstruct.extensions.spring.example.SeatConfigurationDto; +import org.springframework.core.convert.converter.Converter; + +@Mapper(config = MapperSpringConfig.class) +public interface SeatConfigurationMapper extends Converter { + @Mapping(target = "seatCount", source = "numberOfSeats") + @Mapping(target = "material", source = "seatMaterial") + SeatConfigurationDto convert(SeatConfiguration seatConfiguration); +} diff --git a/examples/custom-converter-registration-configuration-with-converter-scan/src/main/java/org/mapstruct/extensions/spring/example/customconfiguration/WheelMapper.java b/examples/custom-converter-registration-configuration-with-converter-scan/src/main/java/org/mapstruct/extensions/spring/example/customconfiguration/WheelMapper.java new file mode 100644 index 0000000..1da1c31 --- /dev/null +++ b/examples/custom-converter-registration-configuration-with-converter-scan/src/main/java/org/mapstruct/extensions/spring/example/customconfiguration/WheelMapper.java @@ -0,0 +1,12 @@ +package org.mapstruct.extensions.spring.example.customconfiguration; + +import org.mapstruct.Mapper; +import org.mapstruct.extensions.spring.example.Wheel; +import org.mapstruct.extensions.spring.example.WheelDto; +import org.springframework.core.convert.converter.Converter; + +@Mapper(config = MapperSpringConfig.class) +public interface WheelMapper extends Converter { + @Override + WheelDto convert(Wheel source); +} diff --git a/examples/custom-converter-registration-configuration-with-converter-scan/src/main/java/org/mapstruct/extensions/spring/example/customconfiguration/WheelsDtoListMapper.java b/examples/custom-converter-registration-configuration-with-converter-scan/src/main/java/org/mapstruct/extensions/spring/example/customconfiguration/WheelsDtoListMapper.java new file mode 100644 index 0000000..ded1c93 --- /dev/null +++ b/examples/custom-converter-registration-configuration-with-converter-scan/src/main/java/org/mapstruct/extensions/spring/example/customconfiguration/WheelsDtoListMapper.java @@ -0,0 +1,13 @@ +package org.mapstruct.extensions.spring.example.customconfiguration; + +import java.util.List; +import org.mapstruct.Mapper; +import org.mapstruct.extensions.spring.example.WheelDto; +import org.mapstruct.extensions.spring.example.Wheels; +import org.springframework.core.convert.converter.Converter; + +@Mapper(config = MapperSpringConfig.class) +public interface WheelsDtoListMapper extends Converter, Wheels> { + @Override + Wheels convert(List source); +} diff --git a/examples/custom-converter-registration-configuration-with-converter-scan/src/main/java/org/mapstruct/extensions/spring/example/customconfiguration/WheelsMapper.java b/examples/custom-converter-registration-configuration-with-converter-scan/src/main/java/org/mapstruct/extensions/spring/example/customconfiguration/WheelsMapper.java new file mode 100644 index 0000000..74fb92b --- /dev/null +++ b/examples/custom-converter-registration-configuration-with-converter-scan/src/main/java/org/mapstruct/extensions/spring/example/customconfiguration/WheelsMapper.java @@ -0,0 +1,14 @@ +package org.mapstruct.extensions.spring.example.customconfiguration; + +import java.util.List; +import org.mapstruct.Mapper; +import org.mapstruct.extensions.spring.example.Wheel; +import org.mapstruct.extensions.spring.example.WheelDto; +import org.mapstruct.extensions.spring.example.Wheels; +import org.springframework.core.convert.converter.Converter; + +@Mapper(config = MapperSpringConfig.class, imports = Wheel.class) +public interface WheelsMapper extends Converter> { + @Override + List convert(Wheels source); +} diff --git a/examples/custom-converter-registration-configuration-with-converter-scan/src/test/java/org/mapstruct/extensions/spring/example/ConversionServiceAdapterIntegrationTest.java b/examples/custom-converter-registration-configuration-with-converter-scan/src/test/java/org/mapstruct/extensions/spring/example/ConversionServiceAdapterIntegrationTest.java new file mode 100644 index 0000000..2819fcc --- /dev/null +++ b/examples/custom-converter-registration-configuration-with-converter-scan/src/test/java/org/mapstruct/extensions/spring/example/ConversionServiceAdapterIntegrationTest.java @@ -0,0 +1,113 @@ +package org.mapstruct.extensions.spring.example; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mapstruct.extensions.spring.example.customconfiguration.ConversionServiceAdapter; +import org.mapstruct.extensions.spring.example.customconfiguration.ConverterScan; +import org.mapstruct.extensions.spring.example.customconfiguration.MapperSpringConfig; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.convert.ConversionService; +import org.springframework.core.convert.TypeDescriptor; +import org.springframework.core.convert.support.DefaultConversionService; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import java.util.ArrayList; +import java.util.List; + +import static org.assertj.core.api.BDDAssertions.then; +import static org.mapstruct.extensions.spring.example.CarType.OTHER; +import static org.mapstruct.extensions.spring.example.SeatMaterial.LEATHER; +import static org.mapstruct.extensions.spring.example.WheelPosition.RIGHT_FRONT; + +@ExtendWith(SpringExtension.class) +public class ConversionServiceAdapterIntegrationTest { + private static final String TEST_MAKE = "Volvo"; + private static final CarType TEST_CAR_TYPE = OTHER; + private static final int TEST_NUMBER_OF_SEATS = 5; + private static final SeatMaterial TEST_SEAT_MATERIAL = LEATHER; + private static final int TEST_DIAMETER = 20; + private static final WheelPosition TEST_WHEEL_POSITION = RIGHT_FRONT; + + @Autowired + private ConversionService conversionService; + + @Configuration + @ComponentScan("org.mapstruct.extensions.spring.example.customconfiguration") + static class ScanConfiguration { + @Bean + public ConversionService conversionService() { + return new DefaultConversionService(); + } + } + + @Test + void shouldKnowAllMappers() { + then(conversionService.canConvert(Car.class, CarDto.class)).isTrue(); + then(conversionService.canConvert(SeatConfiguration.class, SeatConfigurationDto.class)).isTrue(); + then(conversionService.canConvert(Wheel.class, WheelDto.class)).isTrue(); + then(conversionService.canConvert(Wheels.class, List.class)).isTrue(); + then(conversionService.canConvert(List.class, Wheels.class)).isTrue(); + then(conversionService.canConvert( + TypeDescriptor.collection(List.class, TypeDescriptor.valueOf(WheelDto.class)), + TypeDescriptor.valueOf((Wheels.class)))) + .isTrue(); + } + + @Test + void shouldMapAllAttributes() { + // Given + final Car car = new Car(); + car.setMake(TEST_MAKE); + car.setType(TEST_CAR_TYPE); + final SeatConfiguration seatConfiguration = new SeatConfiguration(); + seatConfiguration.setSeatMaterial(TEST_SEAT_MATERIAL); + seatConfiguration.setNumberOfSeats(TEST_NUMBER_OF_SEATS); + car.setSeatConfiguration(seatConfiguration); + final Wheels wheels = new Wheels(); + final ArrayList wheelsList = new ArrayList<>(); + final Wheel wheel = new Wheel(); + wheel.setDiameter(TEST_DIAMETER); + wheel.setPosition(TEST_WHEEL_POSITION); + wheelsList.add(wheel); + wheels.setWheelsList(wheelsList); + car.setWheels(wheels); + + // When + final CarDto mappedCar = conversionService.convert(car, CarDto.class); + + // Then + then(mappedCar).isNotNull(); + then(mappedCar.getMake()).isEqualTo(TEST_MAKE); + then(mappedCar.getType()).isEqualTo(String.valueOf(TEST_CAR_TYPE)); + final SeatConfigurationDto mappedCarSeats = mappedCar.getSeats(); + then(mappedCarSeats).isNotNull(); + then(mappedCarSeats.getSeatCount()).isEqualTo(TEST_NUMBER_OF_SEATS); + then(mappedCarSeats.getMaterial()).isEqualTo(String.valueOf(TEST_SEAT_MATERIAL)); + final WheelDto expectedWheelDto = new WheelDto(); + expectedWheelDto.setPosition(String.valueOf(TEST_WHEEL_POSITION)); + expectedWheelDto.setDiameter(TEST_DIAMETER); + then(mappedCar.getWheels()).hasSize(1).containsExactly(expectedWheelDto); + } + + @Test + void shouldMapGenericSourceType() { + // Given + final WheelDto dto = new WheelDto(); + dto.setPosition(String.valueOf(TEST_WHEEL_POSITION)); + dto.setDiameter(TEST_DIAMETER); + final List dtoList = new ArrayList<>(); + dtoList.add(dto); + + // When + final Wheels convertedWheels = conversionService.convert(dtoList, Wheels.class); + + // Then + final Wheel expectedWheel = new Wheel(); + expectedWheel.setPosition(TEST_WHEEL_POSITION); + expectedWheel.setDiameter(TEST_DIAMETER); + then(convertedWheels).isNotNull().hasSize(1).containsExactly(expectedWheel); + } +} diff --git a/extensions/src/main/java/org/mapstruct/extensions/spring/converter/ConversionServiceAdapterDescriptor.java b/extensions/src/main/java/org/mapstruct/extensions/spring/converter/ConversionServiceAdapterDescriptor.java index f304eed..cc9a978 100644 --- a/extensions/src/main/java/org/mapstruct/extensions/spring/converter/ConversionServiceAdapterDescriptor.java +++ b/extensions/src/main/java/org/mapstruct/extensions/spring/converter/ConversionServiceAdapterDescriptor.java @@ -1,20 +1,27 @@ package org.mapstruct.extensions.spring.converter; import static org.apache.commons.lang3.StringUtils.isNotEmpty; +import static org.mapstruct.extensions.spring.SpringMapperConfig.DEFAULT_CONFIGURATION_CLASS_NAME; +import static org.mapstruct.extensions.spring.SpringMapperConfig.DEFAULT_CONVERSION_SERVICE_BEAN_NAME; import com.squareup.javapoet.ClassName; import java.util.List; public class ConversionServiceAdapterDescriptor { + public static final String DEFAULT_CONVERTER_SCAN_CLASS_NAME = "ConverterScan"; + public static final String DEFAULT_CONVERTER_SCANS_CLASS_NAME = "ConverterScans"; + private ClassName adapterClassName; - private String conversionServiceBeanName; + private String conversionServiceBeanName = DEFAULT_CONVERSION_SERVICE_BEAN_NAME; private List fromToMappings; private boolean lazyAnnotatedConversionServiceBean; + private String configurationClassName = DEFAULT_CONFIGURATION_CLASS_NAME; private boolean generateConverterScan; boolean hasNonDefaultConversionServiceBeanName() { - return isNotEmpty(getConversionServiceBeanName()); + return isNotEmpty(getConversionServiceBeanName()) + && !DEFAULT_CONVERSION_SERVICE_BEAN_NAME.equals(getConversionServiceBeanName()); } public ClassName getAdapterClassName() { @@ -56,6 +63,15 @@ public ConversionServiceAdapterDescriptor lazyAnnotatedConversionServiceBean( return this; } + public ConversionServiceAdapterDescriptor configurationClassName( + final String configurationClassName) { + this.configurationClassName = configurationClassName; + return this; + } + + public String getConfigurationClassName() { + return configurationClassName; + } public boolean isGenerateConverterScan() { return generateConverterScan; @@ -67,14 +83,14 @@ public ConversionServiceAdapterDescriptor generateConverterScan(final boolean ge } public ClassName getConverterScanClassName() { - return ClassName.get(getAdapterClassName().packageName(), "ConverterScan"); + return ClassName.get(getAdapterClassName().packageName(), DEFAULT_CONVERTER_SCAN_CLASS_NAME); } public ClassName getConverterScansClassName() { - return ClassName.get(getAdapterClassName().packageName(), "ConverterScans"); + return ClassName.get(getAdapterClassName().packageName(), DEFAULT_CONVERTER_SCANS_CLASS_NAME); } public ClassName getConverterRegistrationConfigurationClassName() { - return ClassName.get(getAdapterClassName().packageName(), "ConverterRegistrationConfiguration"); + return ClassName.get(getAdapterClassName().packageName(), configurationClassName); } } diff --git a/extensions/src/main/java/org/mapstruct/extensions/spring/converter/ConverterMapperProcessor.java b/extensions/src/main/java/org/mapstruct/extensions/spring/converter/ConverterMapperProcessor.java index c7768c6..c60d844 100644 --- a/extensions/src/main/java/org/mapstruct/extensions/spring/converter/ConverterMapperProcessor.java +++ b/extensions/src/main/java/org/mapstruct/extensions/spring/converter/ConverterMapperProcessor.java @@ -8,6 +8,8 @@ import static javax.lang.model.type.TypeKind.DECLARED; import static javax.tools.Diagnostic.Kind.ERROR; import static org.apache.commons.lang3.StringUtils.defaultIfBlank; +import static org.mapstruct.extensions.spring.SpringMapperConfig.DEFAULT_CONFIGURATION_CLASS_NAME; +import static org.mapstruct.extensions.spring.SpringMapperConfig.DEFAULT_CONVERSION_SERVICE_BEAN_NAME; import static org.mapstruct.extensions.spring.converter.ModelElementUtils.hasName; import com.squareup.javapoet.ClassName; @@ -134,6 +136,8 @@ private ConversionServiceAdapterDescriptor buildAdapterDescriptor( .generateConverterScan(getGenerateConverterScan(annotations, roundEnv)) .lazyAnnotatedConversionServiceBean( getLazyAnnotatedConversionServiceBean(annotations, roundEnv)) + .configurationClassName( + getConfigurationClassName(annotations, roundEnv)) .fromToMappings(getExternalConversionMappings(annotations, roundEnv)); } @@ -241,8 +245,7 @@ private void processMapperAnnotation( .collect(toList())); adapterDescriptor.fromToMappings(fromToMappings); writeAdapterClassFile(adapterDescriptor); - if (adapterDescriptor.hasNonDefaultConversionServiceBeanName() - && adapterDescriptor.isGenerateConverterScan()) { + if (adapterDescriptor.isGenerateConverterScan()) { writeConverterScanFiles(adapterDescriptor); } } @@ -372,7 +375,7 @@ private static boolean isSpringMapperConfigAnnotation(TypeElement annotation) { private void updateFromDeclaration( final MutablePair adapterPackageAndClass, final Element element) { - final SpringMapperConfig springMapperConfig = element.getAnnotation(SpringMapperConfig.class); + final SpringMapperConfig springMapperConfig = toSpringMapperConfig(element); adapterPackageAndClass.setLeft( Optional.of(springMapperConfig.conversionServiceAdapterPackage()) .filter(StringUtils::isNotBlank) @@ -387,7 +390,7 @@ private String getPackageName(Element element) { private static String getConversionServiceBeanName( final Set annotations, final RoundEnvironment roundEnv) { return getConfigAnnotationAttribute( - annotations, roundEnv, SpringMapperConfig::conversionServiceBeanName, null); + annotations, roundEnv, SpringMapperConfig::conversionServiceBeanName, DEFAULT_CONVERSION_SERVICE_BEAN_NAME); } private static Optional findFirstElementAnnotatedWith( @@ -419,6 +422,15 @@ private static boolean getLazyAnnotatedConversionServiceBean( annotations, roundEnv, SpringMapperConfig::lazyAnnotatedConversionServiceBean, TRUE); } + private static String getConfigurationClassName( + final Set annotations, final RoundEnvironment roundEnv) { + return getConfigAnnotationAttribute( + annotations, + roundEnv, + SpringMapperConfig::converterRegistrationConfigurationClassName, + DEFAULT_CONFIGURATION_CLASS_NAME); + } + private static boolean getGenerateConverterScan( final Set annotations, final RoundEnvironment roundEnv) { return getConfigAnnotationAttribute( diff --git a/extensions/src/main/java/org/mapstruct/extensions/spring/converter/ConverterScanGenerator.java b/extensions/src/main/java/org/mapstruct/extensions/spring/converter/ConverterScanGenerator.java index c690e58..f68e57f 100644 --- a/extensions/src/main/java/org/mapstruct/extensions/spring/converter/ConverterScanGenerator.java +++ b/extensions/src/main/java/org/mapstruct/extensions/spring/converter/ConverterScanGenerator.java @@ -15,10 +15,6 @@ public class ConverterScanGenerator extends AdapterRelatedGenerator { ClassName.get(SPRING_CONTEXT_ANNOTATION_PACKAGE_NAME, "ComponentScan"); private static final ClassName IMPORT_CLASS_NAME = ClassName.get(SPRING_CONTEXT_ANNOTATION_PACKAGE_NAME, "Import"); - private static final AnnotationSpec IMPORT_ANNOTATION_SPEC = - AnnotationSpec.builder(IMPORT_CLASS_NAME) - .addMember("value", "$L", "ConverterRegistrationConfiguration.class") - .build(); private static final AnnotationSpec REPEATABLE_ANNOTATION_SPEC = AnnotationSpec.builder(Repeatable.class) .addMember("value", "$L", "ConverterScans.class") @@ -43,12 +39,16 @@ protected JavaFile.Builder modifyDefaultFileBuilder(final JavaFile.Builder javaF protected TypeSpec createMainTypeSpec(final ConversionServiceAdapterDescriptor descriptor) { final var converterScanClassTypeSpecBuilder = TypeSpec.annotationBuilder(descriptor.getConverterScanClassName()).addModifiers(PUBLIC); + final var importAnnotationSpec = + AnnotationSpec.builder(IMPORT_CLASS_NAME) + .addMember("value", "$L", descriptor.getConfigurationClassName() + ".class") + .build(); Optional.ofNullable(buildGeneratedAnnotationSpec()) .ifPresent(converterScanClassTypeSpecBuilder::addAnnotation); converterScanClassTypeSpecBuilder .addAnnotation(COMPONENT_SCAN_CLASS_NAME) .addAnnotation(TARGET_TYPE_ANNOTATION_SPEC) - .addAnnotation(IMPORT_ANNOTATION_SPEC) + .addAnnotation(importAnnotationSpec) .addAnnotation(Documented.class) .addAnnotation(RETENTION_RUNTIME_ANNOTATION_SPEC) .addAnnotation(REPEATABLE_ANNOTATION_SPEC)