第二章:微服务构建:Spring Boot (Spring cloud微服务实战)

本章主要内容:

1.如何构建Spring Boot项目

2.如何实现RESTful API 接口

3.如何实现多环境的Spring Boot应用配置

4.深入理解Spring Boot配置的启动机制


框架简介

Spring Boot 通过设计大量的自动化配置等方式来简化Spring原有样板化的配置,使开发者可以快速的构建应用,除了解决配置问题,还通过一系列的Starter POMs的定义,整合各项功能时,通过类似模板化的Starter模板定义来引用,使得依赖管理工作变的简单。

Spring Boot构建的工程只需要将Spring Boot应用打成jar包,并通过java -jar 命令运行就能启动一个标准化的web应用。不用打包成war包部署到tomcat下运行。


快速入门

环境准备:

      java 7 以及以上版本

      Spring framework 

      maven 


构建maven项目

访问官方地址快速构建项目,地址 : http://start.spring.io/


点击Generate Project下载zip包,并解压,导入开发工具中。

 

工程结构解析:

src/main/java 主程序的入口:DemoApplication,可以直接运行该类启动Spring Boot应用。

src/main/resources:配置目录,该目录用于存放应用的一些配置信息,比如静态资源、配置文件等

src/test/ :单元测试目录


Maven配置分析:

<?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>com.example</groupId>
	<artifactId>demo</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<!-- 默认将应用打包成jar.默认的web依赖会包含嵌入式的tomcat -->
	<packaging>jar</packaging>

	<name>demo</name>
	<description>Demo project for Spring Boot</description>

	<!-- 父项目定义了Spring Boot版本的基础依赖以及一些默认配置内容,比如application.properties的位置等 -->
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.0.1.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>
		<!-- 全栈web开发模块,包含嵌入式的tomcat,spring MVC -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<!-- 通用的测试模块,包含Junit、Hamcrest、Mockito -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<!-- 插件,可以帮助方便的启停服务 -->
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>


</project>


实现RESTful API


package com.example.demo.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {
	
	@RequestMapping("/hello")
	public String index(){
		return "Hello World !";
	}

}

启动应用并访问 http://localhost:8080/hello 我们可以看到返回了预期结果



启动Spring Boot 应用的三种方式:

1.直接通过运行main函数的类来启动

2.使用maven 命令: mvn spring-boot:run 

3.在服务器上部署运行时,先使用mvn install 将应用打包成jar 包,再通过java -jar ***.jar包来启动应用


编写单元测试

package com.example.demo;

import static org.hamcrest.Matchers.equalTo;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;

import com.example.demo.controller.HelloController;

@RunWith(SpringRunner.class)
@SpringBootTest
public class DemoApplicationTests {
	
	private MockMvc mvc;
	
	@Before
	public void setUp(){
		mvc = MockMvcBuilders.standaloneSetup(new HelloController()).build();
	}

	@Test
	public void hello() throws Exception {
		mvc.perform(MockMvcRequestBuilders.get("/hello").accept(MediaType.APPLICATION_JSON))
		.andExpect(status().isOk())
		.andExpect(content().string(equalTo("Hello World !")));
	}

}

配置详解

spring Boot默认的配置文件路劲:src/main/resources/application.properties,关于spring Boot应用的配置内容都可以集中在该文件中,比如容器端口号,应用名等、数据源、日志级别

server.port=8888
spring.application.name=hello

springBoot的配置文件除了可以使用properties文件,还可以使用YMAL。

除了可以配置各个Starter模板中预定义的配置属性,还可以自定义属性,也可以在各个参数之间直接通过PlaceHolder的方式来引用。

book.name=SpringCloudInAction
book.author=zhaiyongchao
book.desc=${book.author} is writing <<${book.name}>>
package com.example.demo.model;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class Book {
	
	@Value("${book.name}")
	private String name;
	
	@Value("${book.author}")
	private String author;
	
	@Value("${book.desc}")
	private String desc;

	/**
	 * @return the name
	 */
	public String getName() {
		return name;
	}

	/**
	 * @param name the name to set
	 */
	public void setName(String name) {
		this.name = name;
	}

	/**
	 * @return the author
	 */
	public String getAuthor() {
		return author;
	}

	/**
	 * @param author the author to set
	 */
	public void setAuthor(String author) {
		this.author = author;
	}

	/**
	 * @return the desc
	 */
	public String getDesc() {
		return desc;
	}

	/**
	 * @param desc the desc to set
	 */
	public void setDesc(String desc) {
		this.desc = desc;
	}
	
}

测试类:

package com.example.demo.model;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest
public class BookTest {

	@Autowired
	private Book book;
	
	@Test
	public void test(){
		String name = book.getName();
		String author = book.getAuthor();
		String desc = book.getDesc();
		System.out.println(name);
		System.out.println(author);
		System.out.println(desc);
	}
	
}

测试结果:

SpringCloudInAction
zhaiyongchao
zhaiyongchao is writing <<SpringCloudInAction>>

使用随机数

可以通过${random} 配置来产生随机的int值,long值或者String字符串。

#随机字符串
com.example.demo.blog.value=${random.value}
#随机int
com.example.demo.blog.number=${random.int}
#随机long
com.example.demo.blog.bignumber=${random.long}
#10以内的随机数
com.example.demo.blog.test1=${random.int(10)}
#10-20的随机数
com.example.demo.blog.test2=${random.int[10,20]}
package com.example.demo.model;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest
public class BlogTest {
	
	@Autowired
	private Blog blog;
	
	@Test
	public void test(){
		System.out.println(blog.getName());
		System.out.println(blog.getCount());
		System.out.println(blog.getTotolCount());
		System.out.println(blog.getTest1());
		System.out.println(blog.getTest2());
	}

}

package com.example.demo.model;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class Blog {
	
	@Value("${com.example.demo.blog.value}")
	private String name;
	@Value("${com.example.demo.blog.number}")
	private int count ;
	@Value("${com.example.demo.blog.bignumber}")
	private long totolCount;
	@Value("${com.example.demo.blog.test1}")
	private int test1;
	@Value("${com.example.demo.blog.test2}")
	private int test2;

	/**
	 * @return the name
	 */
	public String getName() {
		return name;
	}

	/**
	 * @param name the name to set
	 */
	public void setName(String name) {
		this.name = name;
	}

	/**
	 * @return the count
	 */
	public int getCount() {
		return count;
	}

	/**
	 * @param count the count to set
	 */
	public void setCount(int count) {
		this.count = count;
	}

	/**
	 * @return the totolCount
	 */
	public long getTotolCount() {
		return totolCount;
	}

	/**
	 * @param totolCount the totolCount to set
	 */
	public void setTotolCount(long totolCount) {
		this.totolCount = totolCount;
	}

	/**
	 * @return the test1
	 */
	public int getTest1() {
		return test1;
	}

	/**
	 * @param test1 the test1 to set
	 */
	public void setTest1(int test1) {
		this.test1 = test1;
	}

	/**
	 * @return the test2
	 */
	public int getTest2() {
		return test2;
	}

	/**
	 * @param test2 the test2 to set
	 */
	public void setTest2(int test2) {
		this.test2 = test2;
	}
	
	

}
package com.example.demo.model;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest
public class BlogTest {
	
	@Autowired
	private Blog blog;
	
	@Test
	public void test(){
		System.out.println(blog.getName());
		System.out.println(blog.getCount());
		System.out.println(blog.getTotolCount());
		System.out.println(blog.getTest1());
		System.out.println(blog.getTest2());
	}

}

测试结果:

6c1bed71d6302dd92b05ea042f664e00
1494119158
7481639510420907711
4
13

多环境配置


多环境配置的文件名需要满足application-{profile}.properties的格式,其中{profile}对应的环境标识,通过在

application.properties中配置属性spring.profiles.active来选择加载相应的配置文件。


spring.profiles.active=dev

application-dev.properties文件内容:

server.port=8080

则服务启动用的8080端口。


加载顺序

1.在命令行中传入的参数

2.spring_application_json中的属性。spring_application_json是以JSON格式配置在系统环境变量中的内容。

3.java:comp/env中的JNDI属性

4.Java的系统属性,可以通过System.getProperties()获得的内容

5.操作系统的环境变量

6.通过random.*配置的随机属性

7.位于当前应用jar包之外,针对不同${profile}环境的配置文件内容,例如application-{profile}.properties或者YMAL配置内容。

8.位于当前应用jar包之内,针对不同${profile}环境的配置文件内容,例如application-{profile}.properties或者YMAL配置内容。

9.位于当前jar包之外的applicaiton.properties和YMAL配置内容

10.位于当前jar包之内的applicaiton.properties和YMAL配置内容

11.在@Configuration注解修饰的类中,通过@PropertySource注解定义的属性。

12.应用默认属性,使用SpringApplication.setDefaultProperties定义的内容





猜你喜欢

转载自blog.csdn.net/dxh0823/article/details/79950883