摘要:我将从我在另一本书中所写的一个短语开始:Spring Boot是用Spring框架创建企业级应用程序的新章节。Spring Boot并不能替代Spring框架;您可以将其看作是用Java社区所使用的框架创建令人敬畏的应用程序的新方法。在这一章中,我将向您展示Spring Boot是什么以及它在幕后是如何工作的。您还将看到Spring Boot的强大功能。那么,为什么我们需要看Spring Boot呢?首先,我们将要使用的所有技术,如Spring Integration、Spring AMQP、Spring Cloud Stream等,都使用Spring Boot 作为它们的基础。书中所有的例子都使用Spring Boot来创建Spring应用程序。当然,Spring Boot使得消息传递更加容易。

一:Spring Boot是什么?

首先,Spring Boot是一种已有的技术。这是什么意思?Spring Boot查看classpath并尝试确定您想要运行哪种类型的应用程序。例如如果你的类路径中有spring mvc模块,Spring Boot的引导将在Spring内部连接WebApplicationInitializer和DispatcherServlet类容器并将建立一个嵌入式容器(Tomcat缺省情况下),所以你可以运行您的应用程序,而无需复制或将应用程序部署到servlet容器中。

Spring Boot的特点

让我们来看看最重要的Spring Boot特性:

1.它可以创建独立的Spring应用程序。基于它的Maven或Gradle插件,你可以创建可执行的jar或war。

2.它有一种基于启动器的固执己见的技术。

3.包括自动配置,它将配置您的Spring应用程序没有任何XML或Java配置类。

4.包括用于web应用程序的嵌入式servlet容器(Tomcat,Jetty,或Undertow)。

5.包括生产就绪特性(非功能性需求)准备使用,如量度和健康检查。

6.Spring Boot不是一个插件或一个代码生成器(这意味着Spring Boot不要创建要编译的文件)。

7.如果您有一个应用程序或servlet容器,您可以部署Spring Boot作为一个war包不用做任务修改。

8.你可以访问所有Spring应用程序事件和监听器(一些东西我们将在下一章讨论)。

这个列表只是Spring Boot所能提供的一些特性;当然还有更多。如果你需要了解更多关于它的信息,我推荐我的另一本书Spring Boot from Apress。这本书包括了关于Spring Boot如何在内部工作的更全面、更详细的章节。

二:Restful API with Spring Boot

Spring Boot的一个重要特性是,您可以创建可执行jar,并通过执行java -jar yourapp.jar来运行它们。您还可以创建可执行的WAR(web archive),它可以独立运行(在WAR中使用嵌入式容器),或者将它们部署到servlet容器中,而无需将代码中的任何东西链接起来。

本节向您展示了一个基于Restful API,它列出了基于国家代码的货币和汇率。这个项目是一个Spring Boot web应用程序。

我将向您展示应用程序的一些代码片段,因此您可以了解Spring Boot的内容可以使用非常少的代码和没有配置文件。

我假设你已经有了代码。我建议您使用STS(Spring Tool Suite),您可以从https://spring.io/tools/sts/all获得。我使用这个IDE是因为它有很好的运行Spring引导的特性,并且您看到的所有数据都基于这个IDE,但是您可以选择任何您喜欢的IDE。

The rest-api-demo Project

这个项目是一个Spring Boot的web应用程序,它将暴露一个Restful端点并公开显示一个国家货币和其他国家的汇率,这个项目在名为ch02的文件夹中。

这个项目也使用了JPA,H2(一个内存数据库),AOP。公开的端点列在表2-1中

Spring Boot Messaging Chapter 2 Spring Boot_spring

清单2-1显示了JSON响应的一个示例。你可以使用一个基本参数也就是端点。

清单2。JSON货币响应-/currenc/latest

Spring Boot Messaging Chapter 2 Spring Boot_java_02

清单2-1通过访问/curren/latest 端点来显示结果响应。它显示基本货币,在这种情况下是美元,以及所有你能得到的利率(货币)来自其他国家的1美元。

对于转换,你请求站点 /currency/{amount}/{base}/to/{code}.想象一下,你想知道有多少日本日元等于10美元.请求可以

像这样做:/currency/10/usd/to/jpy.您应该得到如清单2-2所示的结果。

Spring Boot Messaging Chapter 2 Spring Boot_Spring Boot_03

清单2-2显示了转换端点的结果。让我们回顾一下其他的文件。

The pom.xml File 

<?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">
<groupId>com.micai.spring</groupId>
<artifactId>Rest-Api-Demo</artifactId>
<version>1.0-SNAPSHOT</version>
<modelVersion>4.0.0</modelVersion>
<packaging>war</packaging>

<name>Rest-Api-Demo</name>
<url>http://www.example.com</url>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!--引入了Spring Boot默认的HTTP引擎Tomcat。-->
<!--<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>-->
<!--热部署插件-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>

<!-- DB dependency -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>

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

The Rate.java Class

package com.micai.spring.messaging.domain;

import com.fasterxml.jackson.annotation.JsonIgnore;

import javax.persistence.*;
import java.util.Date;

/**
* @Auther: zhaoxinguo
* @Date: 2018/8/6 14:13
* @Description:
*/
@Entity
@Table(name = "rate")
public class Rate {

@Id
private String code;
private Float rate;

@JsonIgnore
@Temporal(TemporalType.DATE)
private Date date;

public Rate() {

}

public Rate(String code, Float rate, Date date) {
super();
this.code = code;
this.rate = rate;
this.date = date;
}

public String getCode() {
return code;
}

public void setCode(String code) {
this.code = code;
}

public Float getRate() {
return rate;
}

public void setRate(Float rate) {
this.rate = rate;
}

public Date getDate() {
return date;
}

public void setDate(Date date) {
this.date = date;
}
}

The RateRepository.java Class

package com.micai.spring.messaging.repository;

import com.micai.spring.messaging.domain.Rate;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import java.util.Date;
import java.util.List;

/**
* @Auther: zhaoxinguo
* @Date: 2018/8/6 14:22
* @Description:
*/
@Repository
public interface RateRepository extends JpaRepository<Rate, String> {

List<Rate> findByDate(Date date);

Rate findByDateAndCode(Date date, String code);

}

The CurrencyController.java Class

package com.micai.spring.messaging.controller;

import com.micai.spring.messaging.domain.CurrencyConversion;
import com.micai.spring.messaging.domain.CurrencyExchange;
import com.micai.spring.messaging.domain.Rate;
import com.micai.spring.messaging.service.CurrencyConversionService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
* @Auther: zhaoxinguo
* @Date: 2018/8/6 14:27
* @Description:
*/
@RestController
@RequestMapping("/currency")
public class CurrencyController {

private static final Logger logger = LoggerFactory.getLogger(CurrencyController.class);

@Autowired
private CurrencyConversionService currencyConversionService;

@RequestMapping("/latest")
public ResponseEntity<CurrencyExchange> getLatest(@RequestParam(name="base",defaultValue=CurrencyExchange.BASE_CODE)String base) throws Exception{
return new ResponseEntity<CurrencyExchange>(new CurrencyExchange(base,new SimpleDateFormat("yyyy-MM-dd").format(new Date()),currencyConversionService.calculateByCode(base,new Date())),HttpStatus.OK);
}

@RequestMapping("/{date}")
public ResponseEntity<CurrencyExchange> getByDate(@PathVariable("date") @DateTimeFormat(pattern="yyyy-MM-dd") Date date,
@RequestParam(name="base",defaultValue=CurrencyExchange.BASE_CODE)String base) throws Exception{
return new ResponseEntity<CurrencyExchange>(new CurrencyExchange(base,new SimpleDateFormat("yyyy-MM-dd").format(date),currencyConversionService.calculateByCode(base,date)),HttpStatus.OK);
}

@RequestMapping("/{amount}/{base}/to/{code}")
public ResponseEntity<CurrencyConversion> conversion(@PathVariable("amount")Float amount,
@PathVariable("base")String base,
@PathVariable("code")String code) throws Exception{
CurrencyConversion conversionResult = currencyConversionService.convertFromTo(base, code, amount);
return new ResponseEntity<CurrencyConversion>(conversionResult,HttpStatus.OK);
}

@RequestMapping(path="/new",method = {RequestMethod.POST})
public ResponseEntity<CurrencyExchange> addNewRates(@RequestBody CurrencyExchange currencyExchange) throws Exception{
try{
final Date date = new SimpleDateFormat("yyyy-MM-dd").parse(currencyExchange.getDate());
final Rate[] rates = currencyExchange.getRates();
currencyConversionService.saveRates(rates,date);
}catch(Exception ex){
logger.error(ex.getMessage());
throw ex;
}
return new ResponseEntity<CurrencyExchange>(HttpStatus.CREATED);
}

}

The RestApiDemoApplication.java Class

package com.micai.spring.messaging;

import com.micai.spring.messaging.domain.Rate;
import com.micai.spring.messaging.repository.RateRepository;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

import java.util.Date;

/**
* @Auther: zhaoxinguo
* @Date: 2018/8/6 14:28
* @Description:
*/
@SpringBootApplication
public class RestApiDemoApplication {

public static void main(String [] args) {
SpringApplication.run(RestApiDemoApplication.class, args);
}

@Bean
public CommandLineRunner data(RateRepository repository) {
return (args) -> {
repository.save(new Rate("EUR",0.88857F,new Date()));
repository.save(new Rate("JPY",102.17F,new Date()));
repository.save(new Rate("MXN",19.232F,new Date()));
repository.save(new Rate("GBP",0.75705F,new Date()));
};
}
}

Running the Spring Boot Currency Web App

mvn spring-boot:run

curl http://localhost:8080/currency/latest

三:总结:

本章介绍了Spring Boot,讨论了它的一些特性,并解释了它是如何工作的使用Spring MVC创建一个简单的货币Restful应用程序。在下一章中,你将从Spring应用程序事件和监听器开始,这是一种通过观察者发送和消费信息来进行消息传递的方式模式。

四:源代码下载:

​https://gitee.com/micai-code/micai-spring-message/tree/master/Rest-Api-Demo​