本章主要内容:
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配置分析:
4.0.0
com.example
demo
0.0.1-SNAPSHOT
jar
demo
Demo project for Spring Boot
org.springframework.boot
spring-boot-starter-parent
2.0.1.RELEASE
UTF-8
UTF-8
1.8
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-maven-plugin
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 <>
可以通过${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定义的内容