1.2初始化Spring应用程序

1.2初始化Spring应用程序

在本书的学习过程中,将创建Taco Cloud,这是一个在线应用程序,用于订购由真人制作的最美味的食物-玉米饼。 当然,将使用SpringSpring Boot以及各种相关的库和框架来实现此目标。

初始化Spring应用程序的有多个选择。尽管我可以指导你逐步完成手动创建项目目录结构和定义构建规范的步骤,但这却浪费了时间,最好花费更多时间编写应用程序代码。因此,将依靠Spring Initializr来引导应用程序的创建。

Spring Initializr既是一个基于浏览器的Web应用程序,又是一个REST API,它们可以生成一个基本的Spring项目结构,可以使用所需的任何功能充实自己。 使用Spring Initializr的几种方法如下:

  • Web应用程序 http://start.spring.io 创建
  • 使用 curl 命令从命令行创建
  • 使用Spring Boot命令行接口从命令行创建
  • 使用Spring Tool Suite创建一个新项目的时候
  • 使用IntelliJ IDEA创建一个新项目的时候
  • 使用NetBean创建一个新项目的时候

我没有在本章中花费数页来讨论这些选项中的每一个,而是在附录中收集了这些详细信息。在本章以及整本书中,将展示如何使用Spring Tool Suite中对Spring Initializr的支持来创建一个新项目。

顾名思义,Spring Tool Suite是一个绝佳的Spring开发环境。但是它还提供了一个方便的Spring Boot Dashboard功能(至少在撰写本文时)其他任何IDE选项中均不提供。

如果你不是Spring Tool Suite用户,很好,我们是朋友了。跳至附录,用最适合你的Initializr选项代替以下各节中的说明。但是要知道,在本书中,我偶尔会引用特定于Spring Tool Suite的功能,例如Spring Boot Dashboard。如果你不使用Spring Tool Suite,则需要调整这些说明以适合你的IDE

1.2.1使用Spring Tool Suite初始化Spring项目

要开始使用Spring Tool Suite中的新建Spring项目,请转到 “文件” 菜单并选择 “新建”,然后选择 “Spring Starter Project”。图1.2显示了要查找的菜单结构。

![1.2使用Spring Tool SuiteInitialzr创建新项目](E:\Document\spring-in-action-v5-translate\第一部分Spring基础\第一章Spring入门\1.2使用Spring Tool SuiteInitialzr创建新项目.jpg)

1.2使用Spring Tool SuiteInitializr创建新项目

一旦选择了Spring Starter Project,就会出现创建新的项目向导对话框(图1.3。向导的第一页要求提供一些常规项目信息,例如项目名称、描述和其他基本信息。如果您熟悉Maven pom.xml文件的内容,则可以将大多数字段识别为以Maven构建规范结尾的项目。对于Taco Cloud应用程序,填写如图1.3所示的对话框,然后单击 “下一步”。

![1.2使用Spring Tool SuiteInitialzr创建新项目](E:\Document\spring-in-action-v5-translate\第一部分Spring基础\第一章Spring入门\1.2使用Spring Tool SuiteInitialzr创建新项目-1571646773838.jpg)

1.3填写Taco Cloud应用程序项目信息

向导的下一页使您可以选择要添加到项目中的依赖项(请参见图1.4。注意,在对话框顶部附近,您可以选择要作为项目基础的Spring Boot版本。默认为最新可用版本。通常,最好保持原样,除非您需要定位其他版本。

至于依赖项本身,您可以展开各个部分并手动查找所需的依赖项,或者在 “可用” 列表顶部的搜索框中搜索它们。对于Taco Cloud应用程序,选择图1.4中所示的依赖项。

![1.4选择依赖](E:\Document\spring-in-action-v5-translate\第一部分Spring基础\第一章Spring入门\1.4选择依赖.jpg)

1.4选择依赖

此时,可以单击完成以生成项目并将其添加到工作区。但是,如果感到有点危险,请再次单击 “下一步”,以查看新的starter项目向导的最后一页,如图1.5所示。

![1.5指定备用Initializr地址(可选)](E:\Document\spring-in-action-v5-translate\第一部分Spring基础\第一章Spring入门\1.5指定备用Initializr地址(可选).jpg)

1.5指定备用Initializr地址(可选)

默认情况下,新项目向导在 http://start.spring.io 上调用Spring Initializr以生成项目。通常,不需要覆盖此默认值,这就是为什么可以在向导第二页上单击 “完成” 的原因。但是,如果由于某种原因要托管自己的Initializr克隆版本(也许是自己计算机上的本地副本,或者是在公司防火墙内运行的自定义克隆版本,那么将需要更改Base Url字段以指向Initializr实例,然后单击完成。

单击完成后,将从Initializr下载该项目并将其加载到工作区中。稍等片刻,使其加载和构建,然后就可以开始开发应用程序功能了。但是首先,让我们看一下Initializr所带来的好处。

1.2.2检查Spring项目结构

IDE中加载项目后,将其展开以查看其中包含的内容。图1.6显示了Spring Tool Suite中扩展的Taco Cloud项目。

![1.6 Spring Tool Suite中的Spring项目结构](E:\Document\spring-in-action-v5-translate\第一部分Spring基础\第一章Spring入门\1.6 Spring Tool Suite中的Spring项目结构.jpg)

1.6 Spring Tool Suite中的Spring项目结构

你可能会认为这是典型的MavenGradle项目结构,其中应用程序源代码位于src/main/java下,测试代码位于src/test/java下,非Java资源位于src/main/resources下 。在该项目结构中,需要注意以下事项:

  • mvnwmvnw.cmd —— 这些是Maven包装器脚本。即使你的计算机上没有安装Maven,也可以使用这些脚本构建项目。
  • pom.xml —— 这是Maven构建规范,一会儿我们将对此进行更深入的研究。
  • TacoCloudApplication.java —— 这是引导项目的Spring Boot主类。稍后,我们将在这节详细介绍。
  • application.properties —— 该文件最初为空,但提供了一个可以指定配置属性的地方。我们将在本章中对此文件进行一些修改,但在第5章中将详细介绍配置属性。
  • static —— 在此文件夹中,可以放置要提供给浏览器的任何静态内容(图像、样式表、JavaScript,最初为空。
  • templates —— 在此文件夹中,放置用于向浏览器呈现内容的模板文件。最初为空,但很快会添加Thymeleaf模板。
  • TacoCloudApplicationTests.java —— 这是一个简单的测试类,可确保成功加载Spring应用程序上下文。开发应用程序时,将添加更多的测试。

随着Taco Cloud应用程序的增长,将使用Java代码、图像、样式表、测试以及其他可帮助完成项目的附带材料来填充此准系统的项目结构。但是与此同时,让我们更深入地研究Spring Initializr提供的一些选项。

探索构建规范

填写Initializr表单时,指定应使用Maven构建项目。因此,Spring Initializr给了你一个pom.xml文件,该文件已经填充了你所做的选择。以下清单显示了Initializr提供的整个pom.xml文件。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
        http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>sia</groupId>
    <artifactId>taco-cloud</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>taco-cloud</name>
    <description>Taco Cloud Example</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.4.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-java</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>htmlunit-driver</artifactId>
            <scope>test</scope>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

xml文件中第一个值得注意的项是 <packaging> 元素。你选择将应用程序构建为可执行的JAR文件,而不是WAR文件。这可能是你所做的最奇怪的选择之一,特别是对于web应用程序。毕竟,传统的Java web应用程序被打包为WAR文件,而JAR文件是库和偶尔使用的桌面UI应用程序的首选打包方式。

选择JAR打包是一种不切实际的选择。虽然WAR文件非常适合部署到传统的Java应用服务器,但是它们并不适合大多数云平台。尽管一些云平台(如Cloud Foundry)能够部署和运行WAR文件,但是所有的Java云平台都能够运行可执行的JAR文件。因此,Spring Initializr默认为JAR打包,除非你不让它这样做。

如果打算将应用程序部署到传统的Java应用服务器,那么需要选择WAR打包并包含web初始化类。我们将在第2章中更详细地讨论如何构建WAR文件。

接下来,请注意 <parent> 元素,更具体地说,注意它的 <version> 子元素。这指定您的项目将 spring-boot-starter-parent 作为它的父POM。除此之外,这个父POM还为Spring项目中常用的几个库提供依赖项管理。对于父POM覆盖的那些库,不必指定版本,因为它是从父POM继承的。2.0.4.RELEASE 版本,表示你正在使用Spring Boot 2.0.4,这样项目将使用继承自Spring Boot版本中定义的依赖项管理。

在讨论依赖项时,请注意在 <dependencies> 元素下声明了三个依赖项。前两个看起来应该比较熟悉。它们直接对应于在单击Spring Tool Suite新建项目向导中的Finish按钮之前选择的WebThymeleaf依赖项。第三个依赖项提供了许多有用的测试功能,你不必选中包含它的方框,因为Spring Initializr假定(希望是正确的)你将编写测试。

你可能还会注意到,所有这三个依赖项的artifact ID中都有starter这个词。Spring Boot starter依赖项的特殊之处在于,它们本身通常没有任何库代码,而是间接地引入其他库。这些starter依赖提供了三个主要的好处:

  • 构建的文件将会小得多,也更容易管理,因为不需要对每一个可能需要的库都声明一个依赖项。
  • 可以根据它们提供的功能来考虑需要的依赖关系,而不是根据库名来考虑。如果正在开发一个web应用程序,那么将添加web starter依赖项,而不是一个编写web应用程序的各个库的清单。
  • 不用担心library版本问题。可以相信的是,对于给定版本的Spring Boot,可间接地引入的库的版本将是兼容的,只需要考虑使用的是哪个版本的Spring Boot

最后,构建规范以Spring Boot插件结束。这个插件执行一些重要的功能:

  • 提供了一个Maven编译目标,让你能够使用Maven运行应用程序。这将在第1.3.4节中尝试实现这个目标。

  • 确保所有的依赖库都包含在可执行的JAR文件中,并且在运行时类路径中可用。

  • JAR文件中生成一个manifest文件,表示引导类(在本书例子中是 TacoCloudApplication)是可执行JAR的主类。

说到引导类,让我们打开它,仔细看看。

引导应用程序

因为将从一个可执行的JAR运行应用程序,所以在运行JAR文件时,有一个主类来执行是很重要的。还需要至少一个最小的Spring配置文件来引导应用程序。这就是将在 TacoCloudApplication 类中找到的内容,如下面的清单所示。

package tacos;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class TacoCloudApplication {
    public static void main(String[] args) {
        SpringApplication.run(TacoCloudApplication.class, args);
    }
}

虽然 TacoCloudApplication 中只有很少的代码,但是其中包含了相当丰富的内容。最强大的代码行之一也是最短的代码行之一。@SpringBootApplication 注释清楚地表明这是一个Spring引导应用程序。但是 @SpringBootApplication 中有更多的东西。@SpringBootApplication 是一个组合了其他三个注释的复合应用程序:

  • @SpringBootConfiguration —— 指定这个类为配置类。尽管这个类中还没有太多配置,但是如果需要,可以将Javabased Spring Framework配置添加到这个类中。实际上,这个注释是@Configuration 注释的一种特殊形式。
  • @EnableAutoConfiguration —— 启用Spring自动配置。稍后我们将详细讨论自动配置。现在,要知道这个注释告诉Spring Boot自动配置它认为需要的任何组件。
  • @ComponentScan —— 启用组件扫描。这允许你声明其他带有 @Component@Controller@Service 等注释的类,以便让Spring自动发现它们并将它们注册为Spring应用程序上下文中的组件。

TacoCloudApplication 的另一个重要部分是 main() 方法。这个方法将在执行JAR文件时运行。在大多数情况下,这种方法是样板代码;编写的每个Spring引导应用程序都有一个类似或相同的方法(尽管类名不同

main() 方法调用SpringApplication类上的静态 run() 方法,该方法执行应用程序的实际引导,创建Spring 应用程序上下文。传递给 run() 方法的两个参数是一个配置类和命令行参数。虽然传递给 run() 的配置类不必与引导类相同,但这是最方便、最典型的选择。

你可能不需要更改引导类中的任何内容。对于简单的应用程序,你可能会发现在引导类中配置一两个其他组件很方便,但是对于大多数应用程序,最好为任何没有自动配置的东西创建一个单独的配置类。你将在本书的整个过程中定义几个配置类,因此请注意这些细节。

测试应用程序

测试是软件开发的一个重要部分。认识到这一点后,Spring Initializr提供了一个测试类。下面的清单显示了基准测试类。

package tacos;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest
public class TacoCloudApplicationTests {
    @Test
    public void contextLoads() {
    }
}

TacoCloudApplicationTests 中没有太多东西:类中的一个测试方法是空的。尽管如此,这个测试类确实执行了必要的检查,以确保Spring应用程序上下文能够成功加载。如果做了任何阻止创建Spring应用程序上下文的更改,则此测试将失败,这样你就可以通过解决问题来应对。

还要注意用 @RunWith(SpringRunner.class) 注释的类。@RunWith 是一个JUnit注释,提供了一个测试运行器来引导JUnit运行测试用例。请将清单1.3看作是对它的基准应用程序测试,即将插件应用到JUnit以提供自定义测试行为。在本例中,JUnit被赋予了SpringRunner,这是一个由Spring提供的测试运行程序,它提供了创建一个Spring应用程序上下文的功能,以供测试运行。

其他名字的测试运行器

如果你已经熟悉编写Spring测试,或者正在查看一些现有的基于Spring的测试类,那么你可能已经看到了一个名为 SpringJUnit4ClassRunner 的测试运行器。SpringRunnerSpringJUnit4ClassRunner 的别名,它是在Spring 4.3中引入的,用于删除与特定版本的JUnit (例如,JUnit4)的关联。毫无疑问,别名更易于阅读和输入。

@SpringBootTest 告诉JUnit使用Spring引导功能引导测试。现在,把它看作是在 main() 方法中调用 SpringApplication.run() 的测试类就足够了。在本书的过程中,将多次看到 @SpringBootTest,我们将揭示它的一些功能。

最后,还有测试方法本身。尽管 @RunWith(SpringRunner.class)@SpringBootTest 的任务是加载用于测试的Spring应用程序上下文,但是如果没有任何测试方法,它们将没有任何事情要做。即使没有任何断言或任何类型的代码,这个空的测试方法也会调用两个注释完成它们的工作,并加载Spring应用程序上下文。如果运行过程中有任何问题,测试就会失败。

至此,我们已经完成了对Spring Initializr提供的代码的回顾。看到了一些用于开发Spring应用程序的样板基础,但是仍然没有编写任何代码。现在,启动IDE,掸掉键盘上的灰尘,并向Taco Cloud应用程序添加一些定制代码。

上一页
下一页