【SpringCloud微服务】第2章 微服务构建 Spring Boot
第2章 微服务构建 Spring Boot
2.1 框架简介
Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。其具有如下特点: ①快速构建 通过设计大量的自动化配置等方式,来简化Spring原有样板化的配置,使得开发者可以快速构建应用; ②自动管理依赖 通过一些列Starter POMs的定义,使得依赖管理工作变得更为简单; ③支持运行期内嵌容器 除了很好融入Docker之外,其自身还支持嵌入式的Tomcat、Jetty等容器; ④编码简单 可以使用Gradle和Groovy来开发。 |
2.2 快速入门
2.2.1 项目构建与解析
1.访问http://start.spring.io/ ,添加web依赖,构建Maven的demo项目。
2.导入项目,熟悉目录结构。
<!--注意:Spring Boot 默认的打包方式为jar包,而非war包 --> <packaging>jar</packaging> |
3.创建com.example.demo.web包,编写测试类HelloController.java
package com.example.demo.web;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 编写一个测试类
* <p>Title: HelloController</p>
* @author Liyan
* @date 2018年3月19日 下午7:00:20
*/
@RestController
public class HelloController {
@RequestMapping("/hello")
public String index() {
return "Hello Word!";
}
}
注意:此处有一个小坑,如果你项目运行时报错:Whitelabel Error Page。原因是你的包结构有问题,简单理解:Application.java启动类,要放在Controller包结构的上一层。参见官网文档:
14.2 Locating the main application class
We generally recommend that you locate your main application class in a root package above other classes. The @EnableAutoConfiguration annotation is often placed on your main class, and it implicitly defines a base “search package” for certain items. For example, if you are writing a JPA application, the package of the @EnableAutoConfiguration annotated class will be used to search for @Entity items.
Using a root package also allows the @ComponentScan annotation to be used without needing to specify a basePackage attribute. You can also use the @SpringBootApplication annotation if your main class is in the root package.
Here is a typical layout:
com
+- example
+- myproject
+- Application.java
|
+- domain
| +- Customer.java
| +- CustomerRepository.java
|
+- service
| +- CustomerService.java
|
+- web
+- CustomerController.java
3.运行DemoApplication.java,访问htpp://localhost:8081/hello
2.2.2 编写单元测试
原著中所讲单元测试示例,受版本限制,已经过时,故本处不再赘述,直接上新代码:
1.修改HelloController.java类(方便单元测试中模拟多场景)
package com.example.demo.web;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
* 编写一个测试类
* <p>Title: HelloController</p>
* @author Liyan
* @date 2018年3月19日 下午7:00:20
*/
@RestController
public class HelloController {
@RequestMapping("/hello")
public String index() {
return "Hello Word!";
}
@RequestMapping(value = "/user" , method = RequestMethod.GET)
public String getUser(@RequestParam String username) {
return "查询用户成功,账号:" + username ;
}
@RequestMapping(value = "/user" , method = RequestMethod.POST)
public String insertUser(@RequestParam String username,@RequestParam String password) {
return "新增用户成功,账号:" + username +";密码:"+ password;
}
}
2.在src/test/java中创建HelloControllerTest测试类
package com.example.demo.web;
import java.util.HashMap;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import com.google.common.collect.Maps;
/**
* Spring Boot的单元测试
* <p>Title: HelloControllerTest</p>
* @author Liyan
* @date 2018年3月19日 下午6:58:03
* @RunWith(SpringRunner.class) SpringRunner是spring-test提供的测试执行单元类
* (SpringJUnit4ClassRunner的新名字)
*/
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class HelloControllerTest {
/**
* Spring RestTemplate的便利替代。你可以获取一个普通的或发送基本HTTP认证(使用用户名和密码)的模板
*/
@Autowired
private TestRestTemplate testRestTemplate;
/**
* 注入端口号
*/
@Value("${local.server.port}")
private int port;
@Test
public void index() {
String url = "http://localhost:"+port+"/hello";
String string = testRestTemplate.getForObject(url, String.class);
System.out.println(string);
}
@Test
public void getUser() {
String url = "http://localhost:"+port+"/user?username={username}";
HashMap<String,Object> params = Maps.newHashMap();
params.put("username", "张三");
String string = testRestTemplate.getForObject(url, String.class, params);
System.out.println(string);
}
@Test
public void insertUser() {
String url = "http://localhost:"+port+"/user";
MultiValueMap<String, Object> params = new LinkedMultiValueMap<>();
params.add("username", "张三");
params.add("password", "123");
String string = testRestTemplate.postForObject(url, params, String.class);
System.out.println(string);
}
}
注意:如果粘贴后代码报错,是因为笔者引入了Google的Guava包,当然你可以将报错的“HashMap<String,Object> params = Maps.newHashMap()”替换为“HashMap<String,Object> params = new HashMap<String,Object> ()”,也可以在pom文件中,引入Guava的依赖,当然,笔者更推荐后一种,毕竟Guava包还是很好用的,值得一试。
<!-- 引入google的guava包 -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>19.0</version>
</dependency>
3.逐个运行单元测试即可,不再赘述。
2.3 配置详解
2.3.1 配置文件
①默认位置 src/main/resources/application.properties; ②除了支持传统的properties文件外,还广泛支持YAML文件;
③注意:YAML目前还有一些不足,它无法通过@PropertySource注解来加载配置,但是YAML将属性加载到内存中保存的时候是有序的,所以当配置文件中信息需要具备顺序含义时,YAML的配置方式比起properties配置文件更有优势。 |
2.3.2 自定义参数
①在application.properties中添加:book.name = SpringCloudInAction; ②在应用中可以通过@Value注解来加载这些自定义的参数,比如: @Value(""${book.name}"") private String name; ③@Value注释加载属性值的时候可以支持两种表达式来进行配置: 一种是PlaceHolder方式,格式为 ${....} 另一种是SpEL表达式,格式为 #{...} |
2.3.3 参数引用
在application.properties中,各个参数之间可以直接通过使用PlaceHolder的方式进行引用: book.name=SpringCloud book.author=ZhaiYongChao book.desc=${book.author} is writing 《 ${book.name} 》 |
2.3.4 使用随机数
①格式为 ${random},具体类型: 随机字符串 XXX.value=${random.value} 随机int XXX.number=${random.int} 随机long XXX.bignumber=${random.long} 10以内的随机数 XXX.test1=${random.int(10)} 10~20的随机数 XXX.test2=${random.int[10,20]} ②场景:该配置方式可以设置应用端口等场景,以免在本地调试时出现端口冲突的麻烦。 |
2.3.5 命令行参数
①格式为连续两个减号--就是对application.properties中的属性进行赋值的标识: java -jar xxx.jar--service.port=8888 命令 等价于 在application.properties中添加属性service.port=8888 |
2.4 多环境配置
1.格式要求
①文件名要满足application-{profile}.properties的格式,其中{profile}为对应的环境标识 ②在application.properties文件中通过spring.profiles.active={profile}设置生效 |
2.简单测试
①在src/main/resources目录下创建2个文件,名字分别为: a)application-test.properties [内容为:server.port=8081] b)application-online.properties [内容为:server.port=8082] ②在application.properties中先配置spring.profiles.active = test ③启动后发现端口为8081,再修改spring.profiles.active = online,启动后端口为8082 |
2.5 加载顺序
Spring Boot的属性加载顺序,由优先级高到优先级低:
①在命令行中传入的参数; ②SPRING_APPLICATION_JSON中的属性,SPRING_APPLICATION_JSON是以JSON格式配置 在系统环境变量中的内容; ③java:comp/env中的JNDI属性; ④Java的系统属性,可以通过System.getProperties()获得的内容; ⑤操作系统的环境变量; ⑥通过random.*配置的随机属性; ⑦位于当前应用Jar包之外,针对不同{profile}环境的配置文件内容,例如 application-{profile}.properties或者yaml定义的配置文件; ⑧位于当前应用Jar包之内,针对不同{profile}环境的配置文件内容,例如 application-{profile}.properties或是yaml定义的配置文件; ⑨位于当前应用Jar包之外的application.properties和yaml配置内容; ⑩位于当前应用Jar包之内的application.properties和yaml配置内容; ⑪在@Configuration注解修改类中,通过@PropertySource注解定义的属性; ⑫应用默认属性,使用SpringApplication.setDefaultProperties定义的内容。 |
2.6 监控与管理
2.6.1 简介
①依赖于Starter POMs 中提供了一个特殊模块 spring-boot-starter-actuator ②该模块能自动为Spring Boot构建的应用提供一系列用于监控的端点(该模板本身做了不少扩展,同时根据不同组件,还提供了更多空端点) |
2.6.2 初识 actuator
1.引入maven依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
2.启动后发现多了很多mapper映射
3.访问localhost:8081/actuator/health看一下效果,有个初步印象
2.6.3 原生端点
根据作用,分为三类(具体作用,后面会补充): ①应用配置类:获取应用程序中加载的应用配置、环境变量、自动化配置报告等与SpringBoot应用密切相关的配置类信息; ②度量指标类:获取应用程序运行过程中用于监控的度量指标,比如内存信息、线程池信息、HTTP请求统计等; ③操作控制类:提供了对应用的关闭等操作类功能。 |
上一篇: SpringBoot多环境开发部署
下一篇: 爬取网易云音乐所有歌单信息