MapStruct在编译时会通过CheckStyle检查代码格式,一旦不符合要求,就会编译终止;所以为了在MapStruct加一些日志方便分析,可以先把CheckStley插件去掉。
位于processor模块:

<!--            <plugin>-->
<!--                <groupId>org.apache.maven.plugins</groupId>-->
<!--                <artifactId>maven-checkstyle-plugin</artifactId>-->
<!--                <executions>-->
<!--                    <execution>-->
<!--                        <id>check-style</id>-->
<!--                        <phase>verify</phase>-->
<!--                        <goals>-->
<!--                            <goal>checkstyle</goal>-->
<!--                        </goals>-->
<!--                    </execution>-->
<!--                </executions>-->
<!--            </plugin>-->

MapStruct-DEMO

使用MapStruct时,我们只定义了Interface,具体的Impl是有MapStruct帮我们实现并编译的,这些在我们代码编译时由MapStruct完成。所以要看MapStruct的工作日志,先要写一个简单的Demo。
注意:

  1. 将demo的MapStruct依赖换成我们拉取代码上的版本
  2. 将MapStruct和Demo的JDK设置成一样的,否则Demo编译的时候会报NPE
    MapStruct Demo将FromDTO转成ToDTO
//FromDTO
public class FromDTO {public String name;
}
//ToDTO
public class ToDTO {public String name;
}
//mapper
@Mapper
public interface From2To {From2To from2to = Mappers.getMapper(From2To.class);ToDTO f2t(FromDTO from);
}

MapStruct入口

MapStruct时通过SPI的方式注册、暴露接口的

javax.annotation.processing.Processor(处理入口)

org.mapstruct.ap.MappingProcessor

org.mapstruct.ap.internal.processor.ModelElementProcessor

org.mapstruct.ap.internal.processor.CdiComponentProcessor
org.mapstruct.ap.internal.processor.Jsr330ComponentProcessor
org.mapstruct.ap.internal.processor.MapperCreationProcessor
org.mapstruct.ap.internal.processor.MapperRenderingProcessor
org.mapstruct.ap.internal.processor.MethodRetrievalProcessor
org.mapstruct.ap.internal.processor.SpringComponentProcessor
org.mapstruct.ap.internal.processor.MapperServiceProcessor

MapStruct的MapperCreationProcessor加了一些调试日志,编译demo输出如下

➜  demo mvn clean compile -q
MethodRetrievalProcessor test
MapperCreationProcessor test
From2To
[com.example.map.ToDTO f2t(com.example.map.FromDTO from)]
[com.example.map.ToDTO f2t(com.example.map.FromDTO from)]
MapperRenderingProcessor test
MapperServiceProcessor test

MapperProcessor

Processor Priority
MethodRetrievalProcessor 1
MapperCreationProcessor 1000
SpringComponentProcessor extends AnnotationBasedComponentModelProcessor 1100
Jsr330ComponentProcessor 同上 1100
CdiComponentProcessor 同上 1100
MapperRenderingProcessor 9999
MapperServiceProcessor 将生成的Impl写入文件 10000

MappingProcessor

MappingProcessor是处理入口,通过ServiceLoader加载各Mapper处理器,并按优先级排序,打日志看各处理器执行阶段。

➜  demo mvn clean compile -q
MethodRetrievalProcessor priority=1
MapperCreationProcessor  priority=1000
MapperRenderingProcessor priority=9999
MapperServiceProcessor   priority=10000

ServiceLoader加载各Mapper处理器:

    /*** Retrieves all model element processors, ordered by their priority value* (with the method retrieval processor having the lowest priority value (1)* and the code generation processor the highest priority value.** @return A list with all model element processors.*/private Iterable<ModelElementProcessor<?, ?>> getProcessors() {// TODO Re-consider which class loader to use in case processors are//类加载器加载的注解处理器// loaded from other modules, too@SuppressWarnings("rawtypes")Iterator<ModelElementProcessor> processorIterator = ServiceLoader.load(ModelElementProcessor.class,MappingProcessor.class.getClassLoader()).iterator();List<ModelElementProcessor<?, ?>> processors = new ArrayList<>();while ( processorIterator.hasNext() ) {processors.add( processorIterator.next() );}//按优先级排序Collections.sort( processors, new ProcessorComparator() );return processors;}

按优先级依次执行各MapperProcessor

    /*** Applies all registered {@link ModelElementProcessor}s to the given mapper* type.** @param context The processor context.* @param mapperTypeElement The mapper type element.*/private void processMapperTypeElement(ProcessorContext context, TypeElement mapperTypeElement) {Object model = null;//按优先级依次执行各processorfor ( ModelElementProcessor<?, ?> processor : getProcessors() ) {try {model = process( context, processor, mapperTypeElement, model );}catch ( AnnotationProcessingException e ) {processingEnv.getMessager().printMessage(Kind.ERROR,e.getMessage(),e.getElement(),e.getAnnotationMirror(),e.getAnnotationValue());break;}}}private <P, R> R process(ProcessorContext context, ModelElementProcessor<P, R> processor,TypeElement mapperTypeElement, Object modelElement) {@SuppressWarnings("unchecked")P sourceElement = (P) modelElement;return processor.process( context, mapperTypeElement, sourceElement );}

参考

  1. 深入理解SPI机制
  2. 你应该了解的 Java SPI 机制
  3. mapstruct源码分析
  4. 注解入坑笔记:关于注解使用必须了解的——Annotation、AbstraceProcessor、APT
  5. 注解处理器是干嘛的
  6. 编译时注解(一)AbstractProcessor实战

MapStruct分析相关推荐

  1. 还在用 BeanUtils来做对象转换吗?快试试 MapStruct吧

    点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! 作者:阿进的写字台 https://www.cnblogs ...

  2. Java对象转换方案分析与mapstruct实践

    简介: 随着系统模块分层不断细化,在Java日常开发中不可避免地涉及到各种对象的转换,如:DO.DTO.VO等等,编写映射转换代码是一个繁琐重复且还易错的工作,一个好的工具辅助,减轻了工作量.提升开发 ...

  3. 从面试角度分析CopyOnWriteArrayList源码

    点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! 注:本系列文章中用到的jdk版本均为java8 相比很多同 ...

  4. 【笔记】Java - mapstruct 转换VO、DTO、PO

    github: https://github.com/mapstruct/mapstruct 官网: https://mapstruct.org/ 官方文档: https://mapstruct.or ...

  5. MapStruct - 原理讲解

    简介 MapStruct是用于生成类型安全的bean映射类的Java注解处理器. 你所要做的就是定义一个映射器接口,声明任何需要映射的方法.在编译过程中,MapStruct将生成该接口的实现.此实现使 ...

  6. MapStruct - Couldn‘t retrieve @Mapper annotation

    报错信息 java: Couldn't retrieve @Mapper annotation 原因分析 Maven Pom 切换 MapStruct 版本的时候旧版本残留,没有清理干净,刷新下 Ma ...

  7. mapstruct学习

    一.可使用的业务场景 相信很多同学在编码过程中会遇到从数据库查询A对象的集合数据,然后遍历A对象集合,然后封装到B数据集合中,然后返回B数据集合给调用者. 如: List<A> listA ...

  8. 对象拷贝之Apache BeanUtils、Spring的BeanUtils、Mapstruct、BeanCopier、PropertieyUtils对比(深拷贝)

    大多时候时候使用的是Apache或Spring``BeanUtils,今天,我们来看一下一个更高效的属性拷贝方式:BeanCopier. https://github.com/cglib/cglib ...

  9. springfox源码_springfox 源码分析(四) 配置类初始化

    时间:2019-5-23 12:46:50 地点:单位.家中 @EnableSwagger2 有了二三章的理解,此时我们再来看EnableSwagger2注解的内容 @Retention(value ...

最新文章

  1. 当我们拿到数据进行建模时,如何选择更合适的算法?
  2. 西瓜书第二章 模型评估与选择
  3. 一个Java方法能有多少个参数类型?这个好奇coder做了个实验
  4. 成功解决AttributeError: module tensorflow.image has no attribute resize
  5. loadrunner与事务有关的函数
  6. hiho一下第二周 Hihocoder #1014 : Trie树
  7. Oracle 数据库自动诊断库 ADR(Automatic Diagnostic Repository)简介
  8. 【英语学习】【WOTD】orthography 释义/词源/示例
  9. PyTorch系列入门到精通——DataLoader与Dataset
  10. maker win10有movie_手把手解决win10系统出现windows MovieMaker故障的方法
  11. golang 单元测试进阶篇
  12. Elasticsearch 如何自定义扩展词库?
  13. jQuery之浏览器打印插件
  14. LeetCode记录总结
  15. java中policelisten的用法,中考英语简单句和主谓一致专项语法复习
  16. ChatGPT学习-如何向ChatGPT提问
  17. java笔迹比对_[笔迹]java-其他
  18. 用简单的css实现html网页动态电子相册的功能
  19. RSA算法以及所涉及的数论定理的简单证明
  20. Verycd网站中不能显示下载网址的解决办法

热门文章

  1. Docker部署onlyoffice并完成20最大连接数破解
  2. 企业开源治理案例及开源项目列表
  3. 计算机中丢失uxtheme dll,win7系统丢失uxtheme.dll的解决方法
  4. 基本布局----AbsoluteLayout(绝对布局)
  5. 怎么在电脑桌面上创建一个便签记事 方便用的时候及时打开
  6. 【源代码】关于D_S证据理论和可信度的计算
  7. 从0.1加0.2不等于0.3谈Python浮点数的前世今生
  8. python 化学计量学_比特原子 Atombit
  9. XDOC Office Server 开源了
  10. apk开发教程!那些年Android面试官常问的知识点,2年以上经验必看