querydsl-maven-plugin的原理是,
- 遍历编译后的target/classes里面所有的class,处理所有带Entity注解的class,
- 处理的时候,会把target/classes里面所有的class都加载到Class Loader中,以免带有Entity注解的class依赖到;
- 最后使用反射处理带有Entity注解的class,生成QClass;
编译两次,失败一次,成功一次
问题在第二步,我们要先编译我们写的代码,才能接着执行querydsl-maven-plugin,生成QClass;因为我们的代码中有使用QClass的地方,所以第一次编译肯定会失败,但是会编译成功一部分,因为我们的Entity代码一般是不引用QClass的,所以一般会编译成功,接着我们执行querydsl-maven-plugin插件,这时候Entity的class都编译完了,querydsl-maven-plugin会处理这些class,然后使用反射API获取相关的信息生成QClass,接下来,QClass已经有了,再编译整个项目,就可以编译成功了。
Maven Profile
通过分析querydsl-maven-plugin的源码,只要我们按照如下的步骤编译就可以了:
- 只编译Entity注解及其依赖的class
- 执行querydsl-maven-plugin插件,生成QClass
- 编译整个项目
使用Maven提供的Profile功能可以达到这个目的,下面给出一个例子配置:
<profiles>
<profile>
<id>querydsl-prepare</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<excludes>*</excludes>
<includes>**/domain/model/*.java</includes>
</configuration>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>all</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<build>
<plugins>
<plugin>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-maven-plugin</artifactId>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>jpa-export</goal>
</goals>
<configuration>
<targetFolder>target/generated-sources/java</targetFolder>
<packages>com.fengxin58.cms.ddd.domain.model</packages>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</profile>
</profiles>
要编译整个项目,只要按顺序执行如下的命令就可以了,
- mvn clean
- mvn compile -P querydsl-prepare
- mvn package -P all
注意:
编译querydsl-prepare profile之前一定要保证target/classes里面没有依赖QClass的class,不然在第三步执行querydsl-maven-plugin的时候load到依赖QClass的class,这时候QClass还没生成,会加载失败;