有时现有的代码生成工具还是无法满足项目的需求,写一个maven plugin来生成代码是必须的,不然手动写是要累死人的。
工欲善其事,必先利其器。
1. 首先不熟悉的小伙伴可以直接看官网的例子,讲解了如何执行插件和绑定到类似compile这样的生命周期上。https://maven.apache.org/guides/plugin/guide-java-plugin-development.html
2. 代码整理
这里最好先在新项目里尝试,老项目还是先把要生成的代码统一风格后再做,一是对代码熟悉下,二是方便生成的代码直接覆盖。
3. 不知道大家有没有用过mapstruct这个小工具,它主要是用来帮助转换entity和dto的,应该有很多类似的项目。那么我们肯定会好奇,它是怎么做到的,写一个接口就可以生成代码了。
https://github.com/mapstruct/mapstruct
首先我们就分析一下,主要分两个阶段 1.生成代码 2.让maven编译代码
对于第一个生成代码,这里我们不会去研究mapstruct是用什么黑科技做到的,有兴趣的小伙伴们可以看下https://github.com/mapstruct/mapstruct/blob/master/parent/pom.xml,或者直接去研究它的源码。我们的实现方式就是简单的字符串+java io,如果你觉得太基础,可以用模版引擎+apache common-io这类工具。都是将生成好的字符串输出到文件里,就是生成了代码了。
下面重点讲下maven里如何编译生成的代码。
首先是新建你的mojo类。
@Mojo(name = "generate")
public class NbdGenerateMojo extends AbstractMojo {
public void execute() throws MojoExecutionException {}
}
然后我们想要生成代码,总得有个输出路径。
@Parameter(property = "javaOutput",
defaultValue = "${project.build.directory}/generated-sources")
private String javaOutput;
其实不难发现,mapstruct在我们target目录下就有一个叫做generated-sources的文件夹。
我们在execute方法里写好了生成代码的代码,已经输出到了generated-sources目录下面。
那么问题来了,为什么我的IDE里面还是报错,找不到类呢?
你会发现,如果你直接生成在src目录下,直接mvn install就ok了。而generated-sources却不会。
这是因为,你没有把generated-sources包含在compile的source root下。这就和在idea里右击某个文件夹,把它设为Sources Root是一样的。
@Parameter(property = "project", required = true, readonly = true)
private MavenProject project;
// 在execute方法里加这一句
project.addCompileSourceRoot(javaOutput);
现在你就可以将你的插件引入到你的项目里了。
com.xxx
xxx-maven-plugin
0.0.1
process
generate-sources
generate
没错,就是这么简单,一个代码生成插件就完成了。
另外如果你对插件的注解不熟悉,就看看这个
https://maven.apache.org/developers/mojo-api-specification.html
对${project.build.directory}这类内置属性不熟悉,就看看这个
https://github.com/cko/predefined_maven_properties/blob/master/README.md
另外,当你生成的代码是在一个项目下,而不是在别的module打包好的,你就需要这个plugin将生成的代码compile到classes下,否则服务都起不来,简而言之就是多久一个source目录。
org.codehaus.mojo
build-helper-maven-plugin
3.0.0
generate-sources
add-source
别下次了,点赞收藏走起!