2.1 展现信息
Spring Web应用中,获取和处理数据是控制器的任务,将数据渲染到HTML中并在浏览器中展现是视图的任务。为了支撑taco的创建页面,需要构建如下组件:
- 用来定义taco配料属性的领域类
- 用来获取配料信息并将其传递至视图的Spring MVC控制器类
- 用来在用户的浏览器中渲染配料列表的视图模版
2.1.1 构建领域类
在我们的Taco Cloud中,领域对象包括Taco设计,组成这些设计的配料,顾客,以及顾客下的订单。
定义配料如下:
Spring Web应用中,获取和处理数据是控制器的任务,将数据渲染到HTML中并在浏览器中展现是视图的任务。为了支撑taco的创建页面,需要构建如下组件:
在我们的Taco Cloud中,领域对象包括Taco设计,组成这些设计的配料,顾客,以及顾客下的订单。
定义配料如下:
唯一不变的就是变化 - 希腊哲学家拉克利特(heraclitus)
Spring框架在不断的变化,以解决现代应用开发中的问题,微服务,反应式编程,Spring Boot等等。
任何实际的应用程序都是由很多组件组成的,每个组件负责整个应用功能的一部分,这些组件需要与其他的应用元素进行协调以完成自己的任务。当程序运行时,需要以某种方式创建并引入这些组件。
Spring的核心是提供了一个容器(Container),通常称为Spring应用上下文(Spring application context),会创建和管理应用组件--bean, 会在Spring应用上下文中装配在一起,从而形成一个完整的应用程序。
将bean装配在一起的行为是通过一种基于依赖注入(Dependency Injection, DI)的模式实现的。此时,组件不会再去创建他所依赖的组件并管理他们的生命周期,使用依赖注入的应用依赖于单独的实体(容器)来创建和维护所有的组件,并将其注入到需要他们的bean中。通常,这是通过构造器参数和属性访问方法来实现的。
以前Spring通过一个或多个XML文件来进行依赖的定义,现在一般通过基于注解的方式。
这里我认为无论通过那种方式,只要达到目的即可,没必要学习太多创建项目的方式。
所以,不同于书中介绍,我们使用Intellij Idea来创建

创建好之后,等待依赖下载完毕

探索构建规范
<packaging>, 这里将应用构建成了一个可执行的jar文件,而不是war文件,因为所有的Java云平台都能够运行可执行的JAR文件,所以Spring Initializr基于云思维,默认都是使用JAR打包方式,当然你可以修改。
<parent>,<version>表名项目以 spring-boot-starter-parent作为其父POM,这个父POM为Spring项目常用的一些库提供了依赖管理。
<dependencies>元素下面声明了四个依赖,这些大都是我们之前创建项目的时候选择的
也可以看到好几个是starter依赖(Spring Boot Starter依赖本身不包含库代码,传递性的拉取其他库),其好处:
最后 pom.xml里面还有一个Spring Boot插件:
引导应用
我们通过可执行的JAR文件的形式来运行应用,所以需要有一个主类,它将会在JAR运行的时候被执行。同时还需要一个最小化的Spring配置,以引导该应用。这就是TacoCloudApplication所做的事儿。
TacoCloudApplication的 @SpringBootApplication是一个组合注解:
@SpringBootConfiguration
@Configuration的特殊形式@EnableAutoConfiguration:启用Spring Boot的自动配置@ComponentScan:启用组件扫描TacoCloudApplication的main方法,是JAR文件执行的时候要运行的方法,这里会调用 SpringApplication 的静态run方法,后者会真正执行引用的引导过程,创建Spring应用上下文,传递的参数:
测试应用
这个测试类会执行必要的检查,确保Spring应用上下文能够成功加载
目标:
Spring自带了一个强大的web框架,SpringMVC。
SpringMVC的核心是控制器概念,控制器是处理请求并以某种方式进行信息相应的类。在面向浏览器的应用中,控制器会填充可选的数据模型并将请求传递给一个视图,以便于生成返回给浏览器中的HTML。
下面是一个简单的控制器,用来处理对根路径("/")的请求,并将这些请求转发到主页视图。
package com.chengxuyuancd.tacocloud.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class HomeController {
@GetMapping("/")
public String home() {
return "home";
}
}
@Controller其实并没有做太多的事儿,主要目的是为了让 @ComponentScan将这个类识别为一个组件。所以这里Spring会自动发现它,并创建一个 HomeController的实例作为Spring应用上下文中的bean。@Service, @Component, @Repository都可以做到和 @Controller一样的效果@GetMapping注解,如果针对"/" 发送HTTP GET请求,则这个方法将会处理请求,返回String类型的home值。<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Taco CLoud</title>
</head>
<body>
<h1>Welcome to...</h1>
<img th:src="@{/images/TacoCloud.png}">
</body>
</html>
这里使用了Thymeleaf的th:src属性和 @{...}表达式,用来引用相对于上下文路径的图片作为img的参数。
Spring中静态资源的地址默认是: /src/main/resources/static
一般的测试,对HTML页面进行断言比较困难,但Spring测试提供了一些支持。
我们期望测试对根路径("/")发送一个HTTP GET请求并期望得到成功的结果,结果应该包含"Welcome to..."
package com.chengxuyuancd.tacocloud;
import com.chengxuyuancd.tacocloud.controller.HomeController;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.test.web.servlet.MockMvc;
import static org.hamcrest.Matchers.containsString;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
@WebMvcTest(HomeController.class)
class TacoCloudApplicationTests {
@Autowired
private MockMvc mockMvc;
@Test
void contextLoads() {
}
@Test
void testHomePage() throws Exception {
mockMvc.perform(get("/"))
.andExpect(status().isOk())
.andExpect(view().name("home"))
.andExpect(content().string(containsString("Welcome to...")));
}
}
这里我们没有使用 @SpringBootTest 注解,而是使用 @WebMvcTest,他会让测试在Spring MVC应用的上下文中执行,具体的是,这里会将HomeController注册到Spring MVC中,这样就可以向他发送请求了。
@WebMvcTest也会为测试Spring MVC应用提供Spring环境支持,仿造了Spring MVC的运行机制,测试类被注入了一个MockMvc,能够让测试实现mockup。
测试testHomePage()方法中,首先使用MockMvc对象对"/"根路径发送HTTP GET请求,设置的预期如下:
这里我提供两种我常用的方式:
./mvnw spring-boot:run控制台会打印出来Spring的ASCII字符,以及Tomcat已经在8080端口启动的日志

DevTools为开发人员提供了很多便利:
我们执行了如下步骤:
Spring的核心中有一个是Spring MVC
数据持久化的基础操作
最新版的Spring中,添加了反应式(reactive)风格编程的支持,包括Spring WebFlux
关系型数据库(JPA),文档数据库(Mongo),图数据库(Neo4j)