学习 Spring 实战第5版:spring起步
目录:spring-in-action-5-目录 下一节: spring-in-action-5-编写基础类和design功能
这节是第一课,我将使用IDEA来初始化Spring Boot项目
Spring注解
Spring应用上下文使用bean作为其基本单位。
过去,spring使用xml文件来实现bean的装配,现在spring提倡使用于xml文件等价的Java配置类来完成相同工作。
<bean id="inventoryService"
class="com.example.InventoryService"/>
<bean id="productService"
class="com.example.ProductService"/>
<constructour-arg ref="inventoryService"/>
</bean>
等价的Java配置类,使用@Configuration注解来告知Spring这是一个配置类。会在Spring上下文中提供bean
@Configuration
public class ServiceConfiguration{
@Bean
public InventoryService inventoryService(){
return new InventoryService();
}
@Bean
public ProductService productService(){
return new ProductService(inventoryService());
}
}
同时基于Java的配置会带来多项收益。
- 更强的类型安全性
- 更好的重构能力
只有当Spring不能进行自动配置的时候,上面的两种操作才是必要的。
自动配置
spring的自动配置起源于自动装配(autowiring)和组件扫描(component scanning)。见:spring-in-action-4-装配bean
使用组件扫描技术,Spring能够自动发现应用类路径下的组件,并将它们创建成Spring应用上下文中的bean。
使用自动装配技术,Spring能够自动为组件注入它们所依赖的其他bean。
Spring Boot
Spring Boot提供了更强的自动配置能力。它使用了增强方法自动配置(autoconfiguration)。
Spring Boot能够基于类路径中的条目,环境变量,以及其他因素,合理猜测需要配置的组件并将它们装配在一起。
@SpringBootApplication组合注解
package com.zyj.tacocloud;
import com.zyj.tacocloud.Ingredient.Type;
import com.zyj.tacocloud.data.IngredientRepository;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
/**
* SpringBootApplication SpringBoot应用
* '@SpringBootApplication' 这个注解包含了三个注解
* 用来声明该类为配置类
* 启用SpringBoot的自动配置
* 启用组件扫描
*
* @author ZYJ
*/
@SpringBootApplication
public class TacoCloudApplication {
public static void main(String[] args) {
/*
应用运行
左侧参数是配置类
右侧参数是命令行传递参数
*/
SpringApplication.run(TacoCloudApplication.class, args);
}
}
@SpringBootApplication
是一个组合注解,它组合了其他3个注解:
@SpringBootConfiguration
:将该类声明为配置类。这样我们可以按需添加基于Java的Spring框架配置。其本质上是@Configuration
注解的特殊形式。@EnableAutoConfiguration
:启用Spring Boot的自动配置。这个注解告诉Spring Boot自动配置它认为我们会用到的组件 。@ComponentScan
:启用组件扫描.这样我们就可以对其他类使用@Component``@Controller``@Service
这样的注解.Spring会自动发现它们,并将它们注册为Spring应用上下文中的组件
SpringBoot Application类
作为整个Spring Boot的应用启动类。其包深(package depth)必须要等于会低于其他所有类。不要把启动类放在过深的包里,这会影响Spring Boot的正常启动。
package com.zyj.tacocloud;
import com.zyj.tacocloud.Ingredient.Type;
import com.zyj.tacocloud.data.IngredientRepository;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
/**
* SpringBootApplication SpringBoot应用
* '@SpringBootApplication' 这个注解包含了三个注解
* 用来声明该类为配置类
* 启用SpringBoot的自动配置
* 启用组件扫描
*
* @author ZYJ
*/
@SpringBootApplication
public class TacoCloudApplication {
public static void main(String[] args) {
/*
应用运行
左侧参数是配置类
右侧参数是命令行传递参数
*/
SpringApplication.run(TacoCloudApplication.class, args);
}
}
启动类实际上可以通过extends配置类的方式,在其中配置Spring Boot的一些运行中配置,但是不建议这么做。
如果你有时间,还是新建一个专门的配置类,完成某一项功能的专门配置为好。
@Controller注解
@Controller
注解使得组件扫描将这个类识别为一个组件,这样会创建一个实例作为Spring应用上下文中的bean。
package com.zyj.tacocloud.web;
/**
* @author ZYJ
*/
@Controller
public class DesignTacoController {
...
}
其他类似目的的注解还有:
- @Component
- @Service
- @Repository
@<menthond>
Mapping注解
这包括@GetMapping注解、@PostMapping注解等。它们的作用是向指定视图发送对应的HTPP method请求,比如GET请求,POST请求等等。
package com.zyj.tacocloud;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
/**
* @author ZYJ
*/
@Controller
public class HomeController {
/**
* 表明针对“/”发送 http get 请求
* @author zyj
*/
@GetMapping("/")
public String home() {
//返回视图名
return "home";
}
public String getHomeMapName() {
return home;
}
}
使用@GetMapping注解,表明这个方法将处理请求,并且返回一个String类型的视图名称。
@SpringBootTest注解
package com.zyj.tacocloud;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
/**
* 自己增加的RunWith注解,是junit4中提供的,提供一个测试运行器 runner,本例中是使用Spring提供的SpringRunner.class
* 它是Soring提供的测试运行器,创建测试所需的Spring上下文
*/
@RunWith(SpringRunner.class)
@SpringBootTest
class TacoCloudApplicationTests {
@Test
void contextLoads() {
}
}
@WebMvcTest注解
它提供比@SpringBootTest粒度更小的测试。
这是Spring Boot提供的一个特殊测试注解。它会让这个测试在Spring Mvc应用的上下文中执行。
它会为Spring MVC应用提供Spring环境的支持。
一般用于,我们需要仿造Spring MVC的运行机制,在其中进行一些测试。
测试类可以注入一个MockMvc,让测试实现mockup。
package com.zyj.tacocloud.controller;
import com.zyj.tacocloud.HomeController;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
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.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view;
/**
* 测试web应用
* 针对 HomeController 的 Web 测试
*/
@WebMvcTest(HomeController.class)
class HomeControllerTest {
@BeforeEach
void setUp() {
}
@AfterEach
void tearDown() {
}
//注入MockMvc
@Autowired
private MockMvc mockMvc;
@Test
void home() {
}
@Test
void getHomeMapName() {
}
@Test
public void testHomePage() throws Exception {
// 发起对 "/" 的 GET
mockMvc.perform(get("/"))
// 期望得到HTTP 200
.andExpect(status().isOk())
// 期望得到 home 视图
.andExpect(view().name("home"))
// 期望包含 “Welcome to ...”
.andExpect(content().string(containsString("Welcome to ...")));
}
}
Spring Boot DevTools
DevTools为Spring开发人员提供了一些便利的工具。
- 代码变更后后,应用会自动重启。
- 当面向浏览器的资源(模板、JavaScript、样式表)等发生变化时,会自动刷新浏览器。
- 自动禁用模板缓存
- 如果使用H2数据库,会内置H2控制台
使用某些模板方案,如Thymeleaf、FreeMarker,会缓存模板解析的结果。这样的话,为每个请求提供服务的时候,模板就不用重新解析了。
生产环境中,这是一种很好的特性,会带来一定的性能收益。但在开发环境中,我们最好禁用它,因为不禁用会导致,即使我们手动刷新浏览器,也无法看到模板变更过的效果。
效果等同于自己配置:
DevTools会在运行的时候,自动启动LiveReload服务器。当你浏览器安装LiveReload浏览器插件后,会在模板、图片、样式表、JavaScript等发生变化的时候自动刷新浏览器。
课后作业
模仿前面要求,实际动手来初始化一个Spring Boot项目