Netflix 构建了一个 Spring 应用程序生成器,以提升开发人员生产力。以下是您也能做到的方法。

工程 | Ben Wilcock | 2020年2月24日 | ...

如果你看了Netflix 的 Taylor Wicksell 在 SpringOne Platform 大会上的主题演讲,你就不得不惊叹于他们的工程团队的极高生产力。去年,超过 300 个基于 Spring 的应用程序投入生产——这是一项令人难以置信的成就。

Taylor Wicksell of Netflix's SpringOne Platform Keynote

您的企业可以从 Netflix 学到什么?

在 Netflix,Taylor 和他的 Java 平台团队负责 Java 开发人员体验 (DevEx)。Taylor 的团队只有一个使命:帮助 Netflix 的工程师保持高效——以极高的速度交付高质量代码。这项使命显然正在取得成功。

Netflix's Java Platform Team's Top Technical Priorities

Taylor 的生产力秘诀清单中排在首位的是应用程序生成器。Netflix 发现,当开发人员所需的一切都触手可及时,他们会更快地采用平台。应用程序生成器通过提供有用的指导性框架来帮助开发人员快速上手,从而减少重复劳动并减轻他们的负担。应用程序生成器还鼓励采用处理常见问题的通用方法——如果您有许多团队同时创建微服务,这尤其有用。

Taylor 清单中同样靠前的还有简化对重要库的访问。每个企业都有自己的库——他们依赖这些工具来简化任务或处理底层工作。这些库非常重要,通常包含私有且独特的专有业务逻辑。应用程序生成器可以帮助开发人员轻松访问这些库,而无需深入查阅文档、翻阅 Wiki 或在 Maven 仓库中搜索。

应用程序生成器有用吗?

是的。你可能已经在使用了。我能想到的最好的例子是 start.spring.io,也被称为“Spring Initializr”(尽管也存在其他生成器,例如这个用于 .Net 应用程序的)。

Spring Initializr 让生成 Spring Boot 应用程序变得轻而易举。它成功的秘诀根本不是秘密:它极其易于使用。你可以在浏览器中使用它,或者直接在 IDE 中使用。你甚至可以通过 cURL 或 HTTPie 从命令行使用它,或者通过 Spring Boot CLI 工具使用它。

构建你自己的应用程序生成器

如何构建?当然是使用 Spring!甚至还有一个专门的库。这个库也叫做 Spring Initializr。它是驱动 start.spring.io 的核心库,而且非常容易定制。在本文的其余部分,我们将逐步介绍创建您自己的定制 Initializr 所需的步骤。

为了模拟您在企业内部的操作,在本教程中,我们将缩小部分应用程序生成选项,并包含一些常规 Spring Initializr 不提供的第三方库,即 Axon CQRS 和事件溯源框架。我们将把我们的项目称为“Axon Initializr”。

本教程的完整代码可在这里在 GitHub 上找到。

第一步 - 创建一个 Spring“Web”项目

冒着递归的风险,我们可以使用 start.spring.io 网站来开始构建我们的定制 Axon Initializr!

使用该网站,按照以下截图中的设置创建一个项目。使用 Spring Boot 的最新 GA 版本,并确保包含 "web" 依赖。我们正在构建一个 RESTful Web 服务,因此需要这些库。

Starting a new project at https://start.spring.io

点击绿色的“生成”按钮,将项目下载为 Zip 文件。解压 Zip 文件,并在你的 IDE 或文本编辑器中打开生成的项目文件夹。现在,我们可以开始构建我们的定制 axon-initializr 项目了。

第二步 - 添加 Spring Initializr 库作为依赖

我们需要在 Maven pom.xml 中添加一些条目,以便将 Spring Initializr 库包含在我们的项目中。在 POM 中,按照如下所示为 Spring Initializr 添加一个 dependencyManagement 条目

    <dependencyManagement>
       <dependencies>
           <dependency>
               <groupId>io.spring.initializr</groupId>
               <artifactId>initializr-bom</artifactId>
               <version>0.8.0.RELEASE</version>
               <type>pom</type>
               <scope>import</scope>
           </dependency>
       </dependencies>
   </dependencyManagement>

接下来,在 POM 现有的 <dependencies> 部分中添加几个额外的 Spring Initializr 依赖

    <!-- Existing dependencies omitted here -->
    <dependency>
        <groupId>io.spring.initializr</groupId>
        <artifactId>initializr-web</artifactId>
    </dependency>
    <dependency>
        <groupId>io.spring.initializr</groupId>
        <artifactId>initializr-generator-spring</artifactId>
    </dependency>

initializr-web 依赖带来了 IDE 可以与之通信的预设应用程序生成端点,而 initializr-generator-spring 则带来了关于如何构建 Spring Boot 项目的预设观点(这正是我们想要的)。现在我们就可以定制 Axon Initializr 了。

第三步 - 配置基本的生成器选项

Spring Initializr 库可以基于多种不同的选择(语言、构建工具等)生成应用程序项目。然而,在你的企业中,限制这些选择可能是明智的。通过这种方式,你可以鼓励采用某些方法。(这些就是前面提到的指导性框架。)例如,你的企业可能有偏好的数据库或消息平台,如果你提供其他选项,事情就会变得复杂。

我们使用一个 application.yaml 文件来配置我们的 Axon Initializr。在我们的 axon-initializr 项目中,将 src/main/resources/application.properties 文件重命名为 application.yaml。然后,通过添加以下 YAML 配置开始定制

initializr:
 name:
   value: axon
 description:
   value: 'An Axon Framework Sample Application'
 group-id:
   value: com.benwilcock
  artifact-id:
   value: axon-app
 javaVersions:
   - id: 11
     default: false
   - id: 1.8
     default: true
 languages:
   - name: Java
     id: java
     default: true
   - name: Kotlin
     id: kotlin
     default: false
 packagings:
   - name: Jar
     id: jar
     default: true
 types:
   - name: Maven Project
     id: maven-project
     description: Generate a Maven-based project archive
     tags:
       build: maven
       format: project
     default: true
     action: /starter.zip

这些“initializr:”参数通过指定可用的选择来配置我们的应用程序生成器

  • Java 版本(目前仅限 8 和 11)
  • 语言(Java 和 Kotlin,但不包括 Groovy)
  • 构建和打包(分别为 Maven 和 JAR)。

您会注意到,在某些条目上,有 default: true。此设置会在未做出选择时自动推广我们偏好的选项。

让我们运行一个简单的测试,以确保我们进展顺利。首先,使用以下命令构建并运行新的 initializr 项目

./mvnw package spring-boot:run

然后,在另一个终端中,使用 cURL 访问 initializr 帮助

curl http://localhost:8080

您的终端窗口中的输出应与以下截图类似

Sample terminal output from the half-built axon-initializr

这确认了 axon-initializr 按预期启动并包含了所需的 Spring Initializr 库。但它尚未准备好开始生成 Spring 或 Axon 应用程序。在第一个终端窗口中使用 Ctrl-C 停止 axon-initializr,然后我们将继续进行定制。

第四步 - 添加 Spring 库

添加常规的 Spring 库很简单。我们只需在 YAML 配置的 dependencies: 列表中为每个库创建一个条目。缺点是:YAML 相当冗长。我在这里只展示 Spring Web 项目的一个条目,以便您入门。(其余的都在 GitHub 上。)

依赖条目以 name 开头,后跟一个 content 项目列表。在下面的示例中,您将看到 Web 依赖组,然后是 Spring Web 的条目

initializr:
 #...(omitted the previous stuff here to save space)
 dependencies:
   - name: Web
     content:
       - name: Spring Web
         id: web
         description: Build web, including RESTful, applications using Spring MVC. Uses Apache Tomcat as the default embedded container.
          facets:
            - web
            - json
         links:
           - rel: guide
             href: https://springframework.org.cn/guides/gs/rest-service/
             description: Building a RESTful Web Service
           - rel: reference
             href: https://docs.springframework.org.cn/spring-boot/docs/{bootVersion}/reference/htmlsingle/#boot-features-developing-web-applications
           - rel: guide
             href: https://springframework.org.cn/guides/gs/serving-web-content/
             description: Serving Web Content with Spring MVC
           - rel: guide
             href: https://springframework.org.cn/guides/tutorials/bookmarks/
             description: Building REST services with Spring

您可以从 start.spring.io 配置中的这个示例 YAML 文件中复制任何其他您喜欢的 Spring 相关条目。

第五步 - 添加 Axon 定制库

这是最后一个配置步骤!对于我们的 Axon Initializr,我们需要添加我们的定制 Axon 库。为简洁起见,我在这里只添加一个 Axon 库作为示例。但在定制你的 initializr 时,你可以添加任意多的条目。

initializr:
 dependencies:
   #...(omitted the existing libraries here to save space)
   - name: Axon Tools
     content:
       - name: Axon Framework
         id: axon-starter
         groupId: org.axonframework
         artifactId: axon-spring-boot-starter
         version: 4.2
         description: Brings first-class support for CQRS, Event Sourcing, and DDD to SpringBoot including Commands, Queries, Aggregates, Events, Event Handlers, and more...
          links:
           - rel: axon
             href: https://github.com/AxonFramework
              description: The open-source code repository on GitHub
           - rel: docs
             href: https://docs.axoniq.io/reference-guide/
             description: The reference guide on how to use Axon
           - rel: video-guide
             href: https://www.youtube.com/watch?v=tqn9p8Duy54&list=PL4O1nDpoa5KQkkApGXjKi3rzUW3II5pjm
             description: A full getting started video tutorial for Axon (YouTube).

您可能会注意到此配置与第四步中的配置不同。这是因为我们明确指出了每个库的 Maven 坐标(groupIdartifactIdversion)。这样做是因为 Axon Framework 库位于 Spring 之外,因此我们需要明确指定。

这里的示例只是片段。您可以在这里在 GitHub 上查看完整的 axon-initializr YAML 配置。

从你的 IDE 尝试 Axon Initializr

现在我们已经将所需的配置和定制添加到 axon-initializr 项目中,是时候使用它在 IDE 中生成一个 Axon 应用程序了。

我将使用 IntelliJ IDEA Ultimate Edition 作为我的 IDE,但同样的流畅开发流程也可以很容易地使用 Eclipse、Spring Tools、NetBeans 或 Visual Studio Code 以类似的方式实现。

首先,在你的终端中启动 axon-initializr 服务

./mvnw clean package spring-boot:run

然后,启动 IntelliJ IDEA,选择 File → New → Project...,在下一个屏幕中,在左侧面板中选择 Spring Initializr 作为新的项目类型。然后,在中心面板中将服务终点 URL 切换为 http://localhost:8080,如下图所示

Beginning a new project in IntelliJ IDEA Ultimate

当你点击“下一步”(“Next”)时,你可以开始定制你新的基于 Axon 的应用程序。我们的标准化努力已经取得了回报;默认的项目名称、group id、artifact id、包、打包方式、语言、Java 版本和描述都来自 Axon Initializr 中 application.yaml 的默认设置。

Choosing the basic settings in IntelliJ IDEA

最后,再次点击“下一步”(“Next”)后,我们可以配置我们(尚未生成)的 Axon 应用程序项目。

我们首先从 Axon Initializr 精选的列表中添加所需的依赖。在下面的截图,您可以看到除了各种标准 Spring 库(如 Spring Data JPA 和 Spring for RabbitMQ,如果您添加了它们)之外,我们还可以选择我们的定制库,如 Axon Framework。这一切都无缝工作,将我们偏好的 Spring 库与我们的定制 Axon 库混合在一起。

Choosing our preferred dependencies in IntelliJ IDEA

我们完成了。在 IntelliJ IDEA 中设置了更多项目(例如生成应用程序的文件夹)后,最后一次点击“下一步”(“Next”)按钮将创建我们新的 Axon 应用程序项目,并直接将我们带入 IDE。从那里,我们就可以开始构建我们的 CQRS 应用程序,添加命令(Commands)、查询(Queries)、事件(Events)和聚合(Aggregates)。

总结

如您所见,使用 Spring Initializr 作为基础创建自定义应用程序生成器非常容易,并且极大地改善了我们的开发人员体验。通过添加您偏好的库和其他定制,您可以让开发人员更容易地“做正确的事”,并给他们提供每个人都想要的东西——更多时间来处理真正重要的事情!

我只是触及了 Spring Initializr 定制的可能性的冰山一角。要了解更多关于许多其他定制选项的信息,请查阅官方文档。最后,别忘了本教程附带的代码可以在这里在 GitHub 上找到。

本文最初发表于 pivotal.io

订阅 Spring 新闻通讯

通过 Spring 新闻通讯保持联系

订阅

先行一步

VMware 提供培训和认证,助您加速前进。

了解更多

获取支持

Tanzu Spring 通过一个简单的订阅提供对 OpenJDK™、Spring 和 Apache Tomcat® 的支持和二进制文件。

了解更多

近期活动

查看 Spring 社区的所有近期活动。

查看全部