(十五)Alian 的 Spring Cloud 自动生成项目

一、创建

  我们之前的文章自定义了 archetype 这个是很重要的步骤哦 ,不理解的可以先看:(十二)Alian 的 Spring Cloud 自定义Archetype,然后又自动生成接口API,其实有了这些基础,这章就很简单了。我们知道在微服务中有很多的服务,每个服务都要去创建 domain project ,可能都由不同的人开发,就可能出现整个项目规范不一致或者创建一堆东西很繁琐,本文主要就是为解决这个问题。为了简便,我们还是在文档服务中心修改。

1.1、第一步

二、mvn命令

mvn语法结构

mvn archetype:generate \
    -DarchetypeGroupId=<archetype-groupId> \
    -DarchetypeArtifactId=<archetype-artifactId>  \
    -DarchetypeVersion=<archetype-version> \
    -DinteractiveMode=<interactiveMode> \
    -DarchetypeCatalog=<archetype-catalog> \
    -DgroupId=<groupId> \
    -DartifactId=<artifactId> \
    -Dversion=<version> \
    -Dpackage=<package>

三、生成项目

3.1、配置

  继续改进我们的文档服务中心,增加生成项目的接口,数据库配置如下:

在这里插入图片描述

3.1、属性配置

AppProperties.java

package cn.alian.microservice.doc.config;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;

@Data
@RefreshScope
@ConfigurationProperties(prefix = "app")
public class AppProperties {

    private String mvn;

    private String swaggerTemplatePath;

    private String swaggerJarPath;

    private String configUri;

    private String remoteRepositories;

    private String tmpDir;

    private Gav domain;

    private Gav project;

    @Data
    public static class Gav{
        private String groupId;
        private String artifactId;
        private String version;
        private String packaging;
    }
}

  具体的配置值,在我上面的截图里都有。不要后面用到的时候,这个参数是什么,这些都是在配置中心配置的。

3.2、控制层

CreateProjectController.java

package cn.alian.microservice.doc.controller;


import cn.alian.microservice.common.dto.ApiResponseDto;
import cn.alian.microservice.doc.service.GenerateProjectService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@Slf4j
@RequestMapping("api/v1/project")
@Api(description = "创建项目")
@RestController
public class CreateProjectController {

    @Autowired
    private GenerateProjectService generateProjectService;

    @ApiOperation(value = "生成项目", notes = "生成项目")
    @GetMapping(value = "/generate")
    public synchronized Object generateProject(
            @ApiParam(example = "cn.alian.mall"") @RequestParam String groupId,
            @ApiParam(example = "user") @RequestParam String artifactId,
            @ApiParam(example = "1.0.0-SNAPSHOT") @RequestParam String version) throws Exception {
        log.info("请求的参数: groupId = [" + groupId + "], artifactId = [" + artifactId + "], version = [" + version + "]");
        //参数判断
        if (StringUtils.isAnyBlank(groupId, artifactId, version)) {
            return ApiResponseDto.fail("无效的参数");
        }
        return generateProjectService.generateProject(groupId, artifactId, version);
    }

}

3.3、服务层

GenerateProjectService.java

package cn.alian.microservice.doc.service;

import cn.alian.microservice.common.dto.ApiResponseDto;
import cn.alian.microservice.doc.config.AppProperties;
import cn.alian.microservice.doc.utils.CmdUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.SystemUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;

@Slf4j
@Service
public class GenerateProjectService extends BaseService{

    @Autowired
    private AppProperties appProperties;

    public Object generateProject(String groupId, String artifactId, String version) throws Exception{
        //获取java临时目录
        File tmpDir = SystemUtils.getJavaIoTmpDir();
        //项目生成的目录
        String outputDir = tmpDir.getAbsolutePath() + File.separator + artifactId + System.currentTimeMillis();
        log.info("项目生成的目录:{}", outputDir);
        //domain生成目录
        String domainOutputDir = outputDir + File.separator + this.appProperties.getDomain().getArtifactId();
        log.info("domain生成目录:{}", domainOutputDir);

        //生成domain
        boolean generateDomain = generate(groupId, artifactId, version, this.appProperties.getDomain(), domainOutputDir);
        if (!generateDomain) {
            return ApiResponseDto.fail("生成domain工程失败");
        }
        //domain压缩包目录
        String toZipDomainDir = outputDir + File.separator + "domain-" + artifactId;
        log.info("domain压缩包目录:{}", toZipDomainDir);
        //domain工程的文件拷贝到domain压缩包目录
        FileUtils.copyDirectory(new File(domainOutputDir + File.separator + artifactId), new File(toZipDomainDir));

        //project生成目录
        String projectOutputDir = outputDir + File.separator + this.appProperties.getProject().getArtifactId();
        log.info("project生成目录:{}", projectOutputDir);
        //生成project
        boolean generateProject = generate(groupId, artifactId, version, this.appProperties.getProject(), projectOutputDir);
        if (!generateProject) {
            return ApiResponseDto.fail("生成domain工程失败");
        }
        //project压缩包目录
        String toZipProjectDir = outputDir + File.separator + artifactId;
        log.info("project压缩包目录:{}", toZipProjectDir);
        //project工程的文件拷贝到project压缩包目录
        FileUtils.copyDirectory(new File(projectOutputDir + File.separator + artifactId), new File(toZipProjectDir));

        //压缩包文件
        String outputZip = outputDir + ".zip";
        //把两个工程文件,压缩到压缩包并返回
        return generateZipReponse(outputZip, artifactId + "-" + version, toZipDomainDir, toZipProjectDir);
    }

    private boolean generate(String groupId, String artifactId, String version, AppProperties.Gav gav, String outputDir) throws Exception {
        log.info("generate groupId = [" + groupId + "], artifactId = [" + artifactId + "], version = [" + version + "], gav = [" + gav + "]");
        //获取mvn依赖的cmd
        String mvnDependencyCmd = CmdUtil.getMvnDependencyCmd(appProperties.getMvn(), appProperties.getRemoteRepositories(), gav);
        //执行获取mvn依赖命令
        Process exec = Runtime.getRuntime().exec(mvnDependencyCmd);
        //打印结果
        printProcess(exec);

        //获取生成项目的cmd
        String generateProjectCmd = CmdUtil.getGenerateProjectCmd(appProperties.getMvn(), groupId, artifactId, version, gav, outputDir, appProperties.getConfigUri());
        //执行生成项目cmd命令
        Process process = Runtime.getRuntime().exec(generateProjectCmd);
        //返回结果
        return printProcess(process);
    }
}

  大致的步骤:

  • 定义好临时生成目录及要生成两个工程的目录
  • 生成的domain和project,这里或获取相关依赖,然后调用响应cmd命令(具体的命令在我之前的文章(十三)Alian 的 Spring Cloud 生成接口调用(swagger codegen) BaseService.java 中),把生成的文件拷贝到要压缩的目录
  • 把压缩目录中的文件压缩返回给客户端

四、验证

4.1、请求生成项目

  输入参数:

  • groupId :cn.alian.mall
  • artifactId :user
  • version :1.0.0-SNAPSHOT
    在这里插入图片描述

4.2、生成项目结果

  执行结果:

在这里插入图片描述

4.3、项目结构

在这里插入图片描述
  相对来说还是比较方便的,对一个大的团队来说,还是蛮有必要的,如果大家都是手动创建,难免规范不一致。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值