From 9ee817b2a12d512d5a986bbcaaf3480bcf936012 Mon Sep 17 00:00:00 2001 From: linpeilie Date: Wed, 26 Jun 2024 00:07:26 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0Spring=E5=BB=B6=E8=BF=9F?= =?UTF-8?q?=E5=8A=A0=E8=BD=BD=E7=9A=84=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../linpeilie/processor/ContextConstants.java | 3 +- .../SpringDelayInjectMapperReference.java | 25 ++++++++++ .../processor/SpringComponentProcessor.java | 48 +++++++++++++++++++ ...p.internal.processor.ModelElementProcessor | 1 + .../SpringDelayInjectMapperReference.ftl | 2 + .../mapstruct/MapstructAutoConfiguration.java | 5 ++ .../mapstruct/SpringContextUtils.java | 20 ++++++++ 7 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/enhance/model/SpringDelayInjectMapperReference.java create mode 100644 mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/enhance/processor/SpringComponentProcessor.java create mode 100644 mapstruct-plus-processor/src/main/resources/io/github/linpeilie/processor/enhance/model/SpringDelayInjectMapperReference.ftl create mode 100644 mapstruct-plus-spring-boot-starter/src/main/java/io/github/linpeilie/mapstruct/SpringContextUtils.java diff --git a/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/ContextConstants.java b/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/ContextConstants.java index 7344696..14013b4 100644 --- a/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/ContextConstants.java +++ b/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/ContextConstants.java @@ -65,7 +65,8 @@ public interface ContextConstants { interface ComponentModelConfig { String qualifiedClassName = "io.github.linpeilie.annotations.ComponentModelConfig"; - String defaultComponentModel = MappingConstants.ComponentModel.SPRING; + String springLazy = "spring-lazy"; + String defaultComponentModel = springLazy; } interface ConvertAdapter { diff --git a/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/enhance/model/SpringDelayInjectMapperReference.java b/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/enhance/model/SpringDelayInjectMapperReference.java new file mode 100644 index 0000000..a2b5d2d --- /dev/null +++ b/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/enhance/model/SpringDelayInjectMapperReference.java @@ -0,0 +1,25 @@ +package io.github.linpeilie.processor.enhance.model; + +import io.github.linpeilie.processor.enhance.processor.SpringComponentProcessor; +import java.util.HashSet; +import java.util.Set; +import org.mapstruct.ap.internal.model.MapperReference; +import org.mapstruct.ap.internal.model.common.Type; + +public class SpringDelayInjectMapperReference extends MapperReference { + + private final Type springContextUtil; + + public SpringDelayInjectMapperReference(Type type, String variableName, boolean isUsed, Type springContextUtil) { + super(type, variableName, isUsed); + this.springContextUtil = springContextUtil; + } + + @Override + public Set getImportTypes() { + Set importTypes = new HashSet<>(); + importTypes.add(getType()); + importTypes.add(springContextUtil); + return importTypes; + } +} diff --git a/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/enhance/processor/SpringComponentProcessor.java b/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/enhance/processor/SpringComponentProcessor.java new file mode 100644 index 0000000..8d74245 --- /dev/null +++ b/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/enhance/processor/SpringComponentProcessor.java @@ -0,0 +1,48 @@ +package io.github.linpeilie.processor.enhance.processor; + +import io.github.linpeilie.processor.ContextConstants; +import io.github.linpeilie.processor.enhance.model.SpringDelayInjectMapperReference; +import io.github.linpeilie.utils.CollectionUtils; +import java.util.Collections; +import java.util.List; +import org.mapstruct.ap.internal.gem.InjectionStrategyGem; +import org.mapstruct.ap.internal.model.Annotation; +import org.mapstruct.ap.internal.model.Field; +import org.mapstruct.ap.internal.model.Mapper; +import org.mapstruct.ap.internal.processor.AnnotationBasedComponentModelProcessor; + +public class SpringComponentProcessor extends AnnotationBasedComponentModelProcessor { + + private Annotation component() { + return new Annotation(getTypeFactory().getType("org.springframework.stereotype.Component")); + } + + @Override + protected String getComponentModelIdentifier() { + return ContextConstants.ComponentModelConfig.springLazy; + } + + @Override + protected List getTypeAnnotations(Mapper mapper) { + return CollectionUtils.newArrayList(component()); + } + + @Override + protected List getMapperReferenceAnnotations() { + return Collections.emptyList(); + } + + @Override + protected boolean requiresGenerationOfDecoratorClass() { + return true; + } + + @Override + protected Field replacementMapperReference(Field originalReference, + List annotations, + InjectionStrategyGem injectionStrategy) { + return new SpringDelayInjectMapperReference(originalReference.getType(), originalReference.getVariableName(), + originalReference.isUsed(), + getTypeFactory().getType("io.github.linpeilie.mapstruct.SpringContextUtils")); + } +} diff --git a/mapstruct-plus-processor/src/main/resources/META-INF/services/org.mapstruct.ap.internal.processor.ModelElementProcessor b/mapstruct-plus-processor/src/main/resources/META-INF/services/org.mapstruct.ap.internal.processor.ModelElementProcessor index a144912..98cd7a9 100644 --- a/mapstruct-plus-processor/src/main/resources/META-INF/services/org.mapstruct.ap.internal.processor.ModelElementProcessor +++ b/mapstruct-plus-processor/src/main/resources/META-INF/services/org.mapstruct.ap.internal.processor.ModelElementProcessor @@ -12,3 +12,4 @@ org.mapstruct.ap.internal.processor.MethodRetrievalProcessor org.mapstruct.ap.internal.processor.SpringComponentProcessor org.mapstruct.ap.internal.processor.MapperServiceProcessor io.github.linpeilie.processor.solon.SolonComponentProcessor +io.github.linpeilie.processor.enhance.processor.SpringComponentProcessor diff --git a/mapstruct-plus-processor/src/main/resources/io/github/linpeilie/processor/enhance/model/SpringDelayInjectMapperReference.ftl b/mapstruct-plus-processor/src/main/resources/io/github/linpeilie/processor/enhance/model/SpringDelayInjectMapperReference.ftl new file mode 100644 index 0000000..894e219 --- /dev/null +++ b/mapstruct-plus-processor/src/main/resources/io/github/linpeilie/processor/enhance/model/SpringDelayInjectMapperReference.ftl @@ -0,0 +1,2 @@ +<#-- @ftlvariable name="" type="io.github.linpeilie.processor.enhance.model.SpringDelayInjectMapperReference" --> +private <@includeModel object=type/> ${variableName} = SpringContextUtils.getBean(<@includeModel object=type/>.class); \ No newline at end of file diff --git a/mapstruct-plus-spring-boot-starter/src/main/java/io/github/linpeilie/mapstruct/MapstructAutoConfiguration.java b/mapstruct-plus-spring-boot-starter/src/main/java/io/github/linpeilie/mapstruct/MapstructAutoConfiguration.java index 23743f5..28c7a06 100644 --- a/mapstruct-plus-spring-boot-starter/src/main/java/io/github/linpeilie/mapstruct/MapstructAutoConfiguration.java +++ b/mapstruct-plus-spring-boot-starter/src/main/java/io/github/linpeilie/mapstruct/MapstructAutoConfiguration.java @@ -24,4 +24,9 @@ public class MapstructAutoConfiguration { return new Converter(converterFactory); } + @Bean + public SpringContextUtils springContextUtils() { + return new SpringContextUtils(); + } + } diff --git a/mapstruct-plus-spring-boot-starter/src/main/java/io/github/linpeilie/mapstruct/SpringContextUtils.java b/mapstruct-plus-spring-boot-starter/src/main/java/io/github/linpeilie/mapstruct/SpringContextUtils.java new file mode 100644 index 0000000..b34275f --- /dev/null +++ b/mapstruct-plus-spring-boot-starter/src/main/java/io/github/linpeilie/mapstruct/SpringContextUtils.java @@ -0,0 +1,20 @@ +package io.github.linpeilie.mapstruct; + +import org.springframework.beans.BeansException; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; + +public class SpringContextUtils implements ApplicationContextAware { + + private static ApplicationContext applicationContext; + + @Override + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + SpringContextUtils.applicationContext = applicationContext; + } + + public static T getBean(Class clazz) { + return applicationContext.getBean(clazz); + } + +}