微服务构建 Spring Boot

Posted Ethan_LiYan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了微服务构建 Spring Boot相关的知识,希望对你有一定的参考价值。

2章 微服务构建 Spring Boot


2.1 框架简介

Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。其具有如下特点:

快速构建

通过设计大量的自动化配置等方式,来简化Spring原有样板化的配置,使得开发者可以快速构建应用;

自动管理依赖

通过一些列Starter POMs的定义,使得依赖管理工作变得更为简单;

支持运行期内嵌容器

除了很好融入Docker之外,其自身还支持嵌入式的TomcatJetty等容器;

编码简单

可以使用GradleGroovy来开发。

2.2 快速入门

2.2.1 项目构建与解析

1.访问http://start.spring.io/  ,添加web依赖,构建Mavendemo项目。

 

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);
	

注意:如果粘贴后代码报错,是因为笔者引入了GoogleGuava包,当然你可以将报错的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文件

properties文件

environments:

   dev:

      url: http://dev.bar.com

      name: Developer Setup

   prod:

      url: http://foo.bar.com

      name: My Cool App

environments.dev.url = http://dev.bar.com

environments.dev.name = Developer Setup

environments.prod.url = http://foo.bar.com

environments.prod.name = My Cool App

③注意: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个文件,名字分别为:

   aapplication-test.properties  [内容为:server.port=8081]

   bapplication-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.propertiesyaml配置内容;

⑩位于当前应用Jar包之内的application.propertiesyaml配置内容;

⑪在@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请求统计等;

③操作控制类:提供了对应用的关闭等操作类功能。

 

以上是关于微服务构建 Spring Boot的主要内容,如果未能解决你的问题,请参考以下文章

构建微服务:Spring boot 入门篇

构建微服务:Spring boot 入门篇

(转)构建微服务:Spring boot 入门篇

(转)Spring boot:入门篇

构建微服务:Spring boot

微服务架构最优的落地技术—Spring Boot