如何开发一款Java脚手架工具?
maven多模块可能新手不友好,很多入门新手都在抱怨这块难度有些大,甚至有的人非常希望能像前段一样用脚手架命令完成工作。而对于入行已久的人,这项工作有有些浪费时间,那么如何开发一款Java脚手架工具呢?
1、目前市场上Java脚手架工具都有那些?
spring的脚手架工具,这个是由Spring官方所提供的脚手架工具,是可以集成在idea中使用的。界面简洁清爽。对于新手非常适合。
阿里脚手架,基于Spring脚手架的开源项目,进行二次开发,定制了一些新的功能在上面。比较适合生产使用。不过缺点是不开源,无法进行深度结合企业进行定制。
这两款脚手架各有千秋,首先Spring是提供了标准的API,只要实现Spring的API,就具备跟spring一样的能力,比如可以直接集成在Idea中使用。(如下图示例)
不过缺点是Spring只提供了单模块的工程脚手架,这显然不符合我们的业务开发中使用的分层定义(大部分),而阿里就针对这点提供了阿里的脚手架,是基于Spring进行二次开的,同时也提供了不同的分层模板,供开发同学自行选择。
那以上就是目前市面上存在的大家都知道的脚手架工具的介绍,前面说的脚手架虽好,但是作为一个极客Java开发,是不喜欢使用页面的,必须要基于命令行来做。(如下示例)
这样才显得高级。你是否是一个极客呢?如果是这篇文章就非常适合你,如果不是也没关系,下一篇教程会带大家一起开发一个类似阿里脚手架的工程。
那下面就开始正文了,有过前端开发经验的同学,看到这个脚手架一定会心有所想,这怎么跟vue的脚手架这么像呢?
是的是非常像,因为使用到的技术都是一样的。都是使用Node语言开发的,中间使用到的框架也大差不差的。后面小编会一一介绍。
2、需要使用到的技术有那些?
首先我们确定了我们的项目是运行在控制台上的。那一定是需要一个解释性的语言,能提供选择的不多。
另外我们需要跟命令行做交互动作。这些东西都是有现成框架的。我们不需要了解如何实现,有轮子,我们只需要将轮子组装起来就行了。
命令行框架:commander
可以通过导入该组件提供命令行程序的通用能力,比如输入命令提供命令说明、帮助、或者执行命令动作。如下
它的语法也非常简单。
// 命令行程序const Program = require("commander");// 创建一个命令Program .command("init") // 命令描述 .description("创建一个新的Maven多模块项目") .action(() => { // 动作函数 });12345678910复制代码类型:[java]
命令行交互:inquirer
交互是有规则的。projectInfoQuestionsEn是一个数组,对应一个一个的交互提示。
第一个输入项目的名字。message=“Please enter a project name”,前缀是一个成功的标志,prefix:logSymbols.success;校验规则validate,只能是英文。
第二个提示是输入作者名字。如上类似。提供了校验,过滤,和提示的语法。按照规则写就可以。
const projectInfoQuestionsEn = [{ type: 'input', name: 'projectName', message: 'Please enter a project name', suffix: ':', prefix: logSymbols.success, filter: function (val) { if (val) { return val } else { return 'example' } }, validate: function (val) { if (new RegExp('^[a-zA-Z]*$').test(val)) { return true } else { return 'It is recommended that you use meaningful names and not special characters(-/¥%@)' } } }, { type: 'input', name: 'projectAuthor', message: 'Please enter author', suffix: ':', prefix: logSymbols.success, filter: function (val) { if (val) { return val } else { return 'mvn-cli' } } } ]// 命令行程序const Program = require("commander");// 命令行交互框架const Prompt = require("inquirer");// 创建一个命令Program .command("init") .description("创建一个新的Maven多模块项目") .action(() => { // 配合Program + Prompt Prompt.prompt(projectInfoQuestionsEn).then(result => { console.log("您选择的平台类型信息如下:"); // 构建参数调用业务 ProjectTemplateConfig.projectName = result.projectName ProjectTemplateConfig.projectVersion = result.projectVersion ProjectTemplateConfig.projectDescription = result.projectDescription ProjectTemplateConfig.springBootVersion = result.springBootVersion ProjectTemplateConfig.groupId = result.groupId ProjectTemplateConfig.projectAuthor = result.projectAuthor ProjectTemplateConfig.port = result.port const project = new Project({ projectTemplateConfig: ProjectTemplateConfig }) project.create(); }) });1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162复制代码类型:[java]
命令行颜色:chalk
//打印当前版本号console.log(chalk.cyan(`JMVN CLI v${packageConfig.version}`))12复制代码类型:[java]
如上就是使用到的所有框架和技术了。那么就可以做一个命令行工具,然后那边需要输入的参数,然后走我们的构建逻辑了。
文件渲染引擎:art-template
新一代javascript模板引擎,用于我们渲染module中的pom和SpringBoot引导类和配置文件。语法简单可以直接到官网去查询使用方法。
3、Maven多模块构建逻辑
这里不会详细做说明,主要提供思路。
先创建每一个module。
然后在每个module中创建模块的pom信息,把要创建的模块和依赖关系传递进来(依赖关系比较复杂感兴趣可以看源码)。然后调用模板进行渲染到文件,生成pom文件。
this._createModulePom = function (singleModuleNamed, dependencyManagement) { let projectName = singleModuleNamed.projectName; let packagePath; let bootClassName; if (singleModuleNamed.type === 'web') { packagePath = this.getWebPackagePath(); bootClassName = this._getBootClassName() } this._mavenPomTemplate.create({ root: false, projectName: projectName, projectVersion: singleModuleNamed.version, moduleName: singleModuleNamed.moduleName, // 需要打包的模块应该是jar packaging: singleModuleNamed.type === 'web' ? 'jar' : null, bootClassPath: `${packagePath}.${bootClassName}`, groupId: this._mavenModuleNamespaceConfig.getGroupId(), mavenSurefireJavaVersion: '1.8', dependencies: dependencyManagement.dependencies }, `./${singleModuleNamed.path}/pom.xml`) }123456789101112131415161718192021复制代码类型:[java]
模板文件就是这样。
然后创建父module,生成父pom的方法和子模块类似。
然后给web层添加启动引导类和配置文件。使用到的技术也是文件渲染(art-template)。