Netflix构建Spring应用生成器以提升开发效率,你也可以做到。

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

如果你观看Netflix SpringOne平台主题演讲视频 (Taylor Wicksell),你一定会对他们工程团队的超高效率感到震惊。去年,超过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或HTTPieSpring Boot CLI工具从命令行使用它。

构建你自己的应用生成器

如何操作?当然是用Spring!甚至还有一个库可以实现。这个库也叫做Spring Initializr。它是驱动start.spring.io的核心库,并且非常易于定制。在本文的其余部分,我们将逐步介绍创建你自己的定制Initializr所需的步骤。

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

本教程的完整代码可以在GitHub上找到

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

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

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

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

点击绿色的“Generate”按钮将项目下载为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>

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

    <!-- 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 https://127.0.0.1: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).

您可能会注意到,此配置与步骤 4 中的配置有所不同。这是因为我们明确地指出了每个库的 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 并选择文件 → 新建 → 项目...,在下一个屏幕上,在左侧面板中选择Spring Initializr作为您的新项目类型。然后,在中心面板中将服务端点 URL 切换到https://127.0.0.1:8080,如下所示。

Beginning a new project in IntelliJ IDEA Ultimate

单击“下一步”后,您可以开始自定义新的基于 Axon 的应用程序。我们的标准化工作已经开始见效;默认项目名称、组 ID、构件 ID、包、打包、语言、Java 版本和描述都来自 Axon Initializr 中application.yaml中的默认设置。

Choosing the basic settings in IntelliJ IDEA

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

我们首先从 Axon Initializr 的精选列表中添加所需的依赖项。在下面的屏幕截图中,您可以看到,除了 Spring Data JPA 和 Spring for RabbitMQ(如果您添加了它们)等各种标准 Spring 库之外,我们还可以选择自定义库,例如 Axon Framework。所有这些都无缝地协同工作,将我们首选的 Spring 库与我们的自定义 Axon 库混合使用。

Choosing our preferred dependencies in IntelliJ IDEA

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

总结

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

我只触及了使用Spring Initializr自定义所能实现的功能的表面。要了解有关许多其他自定义选项的更多信息,请查看官方文档。最后,不要忘记,本文教程附带的代码可以在GitHub 上找到

本文最初发表于 pivotal.io

获取 Spring 新闻通讯

与 Spring 新闻通讯保持联系

订阅

领先一步

VMware 提供培训和认证,以加速您的进步。

了解更多

获取支持

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

了解更多

即将举行的活动

查看Spring社区中所有即将举行的活动。

查看全部