聊聊 Spring Boot 2.x 那些事儿

本文目录:html

即将的 Spring 2.0前端

 - Spring 2.0 是什么java

 - 开发环境和 IDEreact

 - 使用 Spring Initializr 快速入门git

Starter 组件程序员

 - Web:REST API & 模板引擎github

 - Data:JPA -> H2web

 - ...spring

生产指标监控 Actuatorshell

内嵌式容器 Tomcat / Jetty / Undertow

Spring 5 & Spring WebFlux

你们看到目录,这么多内容,简直一本书的节奏。若是很详细,确实是。 但是只有一篇文章我大体讲讲每一个点,其是什么,其主要业界的使用场景是什么,而后具体会有对应的博客教程。恩,下面咱们聊聊 Spring 2.0。

1、即将的 Spring 2.0

spring.io 官网有句醒目的话是:

BUILD ANYTHING WITH SPRING BOOT

Java 程序员都知道 Spring 是什么,Spring 走过了这么多个年头。Spring 是 Java 应用程序平台开发框架,确定也是跨平台的。

一样,它也是 Java EE 轻量级框架,为 Java 开发这提供了全面的基础设施支持。

从 SSH(Strusts / Spring / Hibernate) 到 SSM(Spring MVC / Spring / Mabtis) ,到如今一个 S (Spring)就够了的年代。 可见 Spring 愈来愈重要了。那 Spring Boot 是什么?

1. Spring 2.0 是什么

先看看世界上最好的文档来源自官方的《Spring Boot Reference Guide》,是这样介绍的:

0?wx_fmt=png

Spring Boot(英文中是“引导”的意思),是用来简化 Spring 应用的搭建到开发的过程。应用开箱即用,只要经过 “just run”(多是 java -jar 或 tomcat 或 maven 插件 run 或 shell 脚本),就能够启动项目。

两者,Spring Boot 只要不多的 Spring 配置文件(例如那些xml,property)。

由于“习惯优先于配置”的原则,使得 Spring Boot 在快速开发应用和微服务架构实践中获得普遍应用。

Spring 目前是 2.0.0 M5 版本,立刻 2.0 release 了。如图:Spring 2.0 架构图

0?wx_fmt=png

最明显的是 Reactor 模型。

插个小故事,曾经有人问:Spring 这种阻塞的编程技术以及金字塔的结构已经开始被不少公司所摈弃?

个人回答天然是那个图。Spring Boot 2.0 基于 Spring 5 Framework ,提供了异步非阻塞 IO 的响应式 Stream 、非堵塞的函数式 Reactive Web 框架 Spring WebFlux。本文最后我会详细介绍的。

0?wx_fmt=png

2. 开发环境和 IDE

大体介绍了 Spring Boot 2.0 是什么,下面咱们快速入门下 Spring Boot 2.0。常言道,磨刀不误砍柴工砍柴工。在搭建一个 Spring Boot 工程应用前,须要配置好开发环境及安装好开发工具:

  • JDK 1.8+
    Spring Boot 2.x 要求 JDK 1.8 环境及以上版本。另外,Spring Boot 2.x 只兼容 Spring Framework 5.0 及以上版本。

  • Maven 3.2+
    为 Spring Boot 2.x 提供了相关依赖构建工具是 Maven,版本须要 3.2 及以上版本。使用 Gradle 则须要 1.12 及以上版本。Maven 和 Gradle 你们各自挑选下喜欢的就好。

  • IntelliJ IDEA
    IntelliJ IDEA (简称 IDEA)是经常使用的开发工具,也是本书推荐使用的。一样使用 Eclipse IDE 天然也是能够的。

这里额外介绍下,对于 Java 新手或者刚刚认识 Spring 的小伙伴。Spring Boot CLI  是一个学习 Spring Boot 的很好的工具。Spring Boot CLI 是 Spring Boot Commad Line 的缩写,是 Spring Boot 命令行工具。

在 Spring Boot CLI 能够跑 Groovy 脚本,经过简单的 Java 语法就能够快速而又简单的学习 Spring Boot 原型。

Spring Boot CLI  具体快速入门看下我写的地址:https://www.bysocket.com/?p=1982

那最经常使用,最推荐的入门固然是使用 Spring Initializr 。下面介绍下如何使用 Spring Initializr。

3. 使用 Spring Initializr 快速入门

打开  start.spring.io  进行很快速的,Spring Boot 骨架工程生成吧。

Spring 官方提供了名为 Spring Initializr 的网站,去引导你快速生成 Spring Boot 应用。网站地址为:https://start.spring.io,操做步骤以下:

第一步,选择 Maven 或者 Gradle 构建工具,开发语言 Java 、Kotlin 或者 Groovy,最后肯定 Spring Boot 版本号。

这里默认选择 Maven 构建工具、Java 开发语言和 Spring Boot 2.0.0。

第二步,输入 Maven 工程信息,即项目组 groupId 和名字 artifactId。这里对应 Maven 信息为:

  • groupId:demo.springboot

  • artifactId:spring-boot-quickstart
    这里默认版本号 version 为 0.0.1-SNAPSHOT 。三个属性在 Maven 依赖仓库是惟一标识的。

第三步,选择工程须要的 Starter 组件和其余依赖。最后点击生成按钮,便可得到骨架工程压缩包。如图 :

0?wx_fmt=png

在对应的 *Application 增长对应的代码以下:(这来自是官方 demo)

 

@Controller @EnableAutoConfiguration public class Application {    @RequestMapping("/")    @ResponseBody    String home() {        return "Hello World!";    }    public static void main(String[] args) throws Exception {        SpringApplication.run(Application.class, args);    } }

在 IDEA 中直接执行应用启动类,来运行 Spring Boot 应用,会获得下面成功的控制台输出:

 

... 省略 2017-10-15 10:05:19.994  INFO 17963 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) 2017-10-15 10:05:20.000  INFO 17963 --- [           main] demo.springboot.QuickStartApplication    : Started QuickStartApplication in 5.544 seconds (JVM running for 6.802)

访问地址 localhost:8080 ,成功返回 “Hello World!” 的字符串。

这就是 Spring Boot 使用,是否是很方便。介绍下工程的目录结构:

 

├── pom.xml └── src    ├── main    │   ├── java    │   │   └── demo    │   │       └── springboot    │   │           └── Application.java    │   └── resources    │       ├── application.properties    │       ├── static    │       └── templates    └── test        └── java            └── demo                └── springboot                    └── QuickstartApplication Tests.java

这是默认的工程结构,java 目录中是编写代码的源目录,好比三层模型大体会新建三个包目录,web 包负责 web 服务,service 包负责业务逻辑,domain 包数据源服务。对应 java 目录的是 test 目录,编写单元测试的目录。

resources 目录会有 application.properties 应用配置文件,还有默认生成的 static 和 templates 目录,static 用于存放静态资源文件,templates 用于存放模板文件。能够在 application.properties 中自定义配置资源和模板目录

2、Starter 组件

什么是 Starter 组件?

Starter 组件是可被加载在应用中的 Maven 依赖项。Spring Boot 提供了不少 “开箱即用” 的 Starter 组件。只须要在 Maven 配置中添加对应的依赖配置,便可使用对应的 Starter 组件。

例如,添加 spring-boot-starter-web 依赖,就可用于构建 RESTful Web 服务,其包含了 Spring MVC 和 Tomcat 内嵌容器等。

开发中,不少功能是经过添加 Starter 组件的方式来进行实现。下面都是经常使用的组件,还有不少事务、消息、安全、监控、大数据等支持,这里就不介绍了。你们能够同理可得去学习哈。

1. Web:REST API & 模板引擎

在 Web 开发中,常见的场景有传统的 Web MVC 架构和先后端分离架构。

Web MVC 架构

Web MVC 模式很适合 Spring Boot 来开发,View 使用 JSP 或者其余模板引擎(默认支持:FreeMarker 、 Groovy 、 Thymeleaf 、 Mustache)。

传统模式好比获取用户,是从用户 view 层发送获取用户请求到 Spring Boot 提供的用户控制层,而后获取数据封装进 Model,最后将 model 返回到 View。

由于 Spring Boot 基于 Spring ,因此 Spring 能作的,Spring Boot 就能作,并且更加方便,更近快速。

先后端分离架构

先后端分离架构,免不了的是 API 文档做为中间的桥梁。Spring Boot 很方便的开发 REST API,前端经过调用 REST API 获取数据。数据形式多是 JSON 或者 XML 等。

而后进行视图渲染,这里前端也有对应的前端模板引擎。其实 H5 ,PC,APP 均可采起相似的方式实现。这里的 API 文档可使用 Swagger2 或者 APIDOC 来实现。

那具体聊聊 REST API

RESTful 是什么?RESTful(Representational State Transfer)架构风格,是一个 Web 自身的架构风格,底层主要基于 HTTP 协议(ps:提出者就是HTTP协议的做者),是分布式应用架构的伟大实践理论。

RESTful 架构是无状态的,表现为请求-响应的形式,有别于基于 Bower 的SessionId 不一样。Spring Boot 的注解 @RestController 支持实现 RESTful 控制层。

那有个问题?权限怎么控制?
RESTful是无状态的,因此每次请求就须要对起进行认证和受权。

  • 认证
    身份认证,即登陆验证用户是否拥有相应的身份。简单的说就是一个Web页面点击登陆后,服务端进行用户密码的校验。

  • 权限验证(受权)
    也能够说成受权,就是在身份认证后,验证该身份具体拥有某种权限。即针对于某种资源的 CRUD,不一样用户的操做权限是不一样的。

    通常简单项目:作个sign(加密加盐参数)+ 针对用户的 access_token 复杂的话,加入  SLL ,并使用 OAuth2 进行对 token 的安全传输。

再聊聊模板引擎

有人在我博客上评论 模板语言 如今没人用了吧。咱们仍是先了解下,什么是模板语言再说吧。

常见的模板语言都包含如下几个概念:数据(Data)、模板(Template)、模板引擎(Template Engine)和结果文档(Result Documents)。

  • 数据
    数据是信息的表现形式和载体,能够是符号、文字、数字、语音、图像、视频等。

    数据和信息是不可分离的,数据是信息的表达,信息是数据的内涵。数据自己没有意义,数据只有对实体行为产生影响时才成为信息。

  • 模板
    模板,是一个蓝图,即一个与类型无关的类。编译器在使用模板时,会根据模板实参对模板进行实例化,获得一个与类型相关的类。

  • 模板引擎
    模板引擎(这里特指用于Web开发的模板引擎)是为了使用户界面与业务数据(内容)分离而产生的,它能够生成特定格式的文档,用于网站的模板引擎就会生成一个标准的HTML文档。

  • 结果文档
    一种特定格式的文档,好比用于网站的模板引擎就会生成一个标准的HTML文档。

模板语言用途普遍,常见的用途以下:

  • 页面渲染

  • 文档生成

  • 代码生成

  • 全部 “数据+模板=文本” 的应用场景

因此你们看到这个用途,应该不会说没有用了吧。具体按模板语言 Thymeleaf 为例,使用以下

pom.xml Thymeleaf 依赖

使用模板引擎,就在 pom.xml 加入 Thymeleaf 组件依赖:

 

<!-- 模板引擎 Thymeleaf 依赖 --> <dependency>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency>

Thymeleaf 依赖配置

在 Spring Boot 项目中加入 Thymeleaf 依赖,便可启动其默认配置。若是想要自定义配置,能够在 application.properties 配置以下

 

spring.thymeleaf.cache=true # Enable template caching. spring.thymeleaf.check-template=true # Check that the template exists before rendering it. spring.thymeleaf.check-template-location=true # Check that the templates location exists. spring.thymeleaf.enabled=true # Enable Thymeleaf view resolution for Web frameworks. spring.thymeleaf.encoding=UTF-8 # Template files encoding. spring.thymeleaf.excluded-view-names= # Comma-separated list of view names that should be excluded from resolution. spring.thymeleaf.mode=HTML5 # Template mode to be applied to templates. See also StandardTemplateModeHandlers. spring.thymeleaf.prefix=classpath:/templates/ # Prefix that gets prepended to view names when building a URL. spring.thymeleaf.reactive.max-chunk-size= # Maximum size of data buffers used for writing to the response, in bytes. spring.thymeleaf.reactive.media-types= # Media types supported by the view technology. spring.thymeleaf.servlet.content-type=text/html # Content-Type value written to HTTP responses. spring.thymeleaf.suffix=.html # Suffix that gets appended to view names when building a URL. spring.thymeleaf.template-resolver-order= # Order of the template resolver in the chain. spring.thymeleaf.view-names= # Comma-separated list of view names that can be resolved.

Controller 的使用方式,和之前的 Spring 方式一致,具体的Tymeleaf 的语法糖,你们能够看看官方文档 http://www.thymeleaf.org/documentation.html。本案例具体整合教程:https://www.bysocket.com/?p=1973。

2. Data:JPA 、Mybatis

Data,顾名思义是数据。数据存储有 SQL 和 NoSQL:

  • SQL:MySQL 、H2 等

  • NoSQL:Redis、MongoDB、Cassandra、Elasticsearch 等
    天然互联网常见使用的 SQL 关系型数据库是 MySQL。ORM 框架流行的有 Hibernate 和 Mybatis 等,JPA 底层实现使用 Hibernate。下面分别介绍下二者的使用方式

Spring Data JPA 依赖 spring-boot-starter-data-jpa

Spring Data JPA 是 Spring Data 的子项目,用于简化数据访问层的实现,能够方便的实现增删改查、分页、排序。

还有不少常见的其余依赖:Spring Data MongoDB、Spring Data Redis 等。这里 Spring Boot 也有对应的 Starter 组件,名为 spring-boot-starter-data-jpa。

具体整合教程:https://www.bysocket.com/?p=1950

Spring Boot Mybatis 依赖 mybatis-spring-boot-starter

Mybatis 也是业界互联网流行的数据操做层框架。有两种形式进行使用 Mybatis。

第1、纯 Annotation,第2、使用 xml 配置 SQL。我的推荐使用 xml 配置 SQL,  SQL 和业务代码应该隔离,方便和 DBA 校对 SQL。两者 XML 对较长的 SQL 比较清晰。

虽然 XML 形式是我比较推荐的,可是注解形式也是方便的。尤为一些小系统,快速的 CRUD 轻量级的系统。这里可见,mybatis-spring-boot-starter依赖是非官方提供的。

Springboot 整合 Mybatis 的完整 Web 案例教程:https://www.bysocket.com/?p=1610

Spring Boot 整合 Mybatis Annotation 注解的完整 Web 案例教程:https://www.bysocket.com/?p=1811

另外,搜索经常使用 ES,spring-data-elasticsearch 是 Spring Data 的 Community modules 之一,是 Spring Data 对 Elasticsearch 引擎的实现。 

Elasticsearch 默认提供轻量级的 HTTP Restful 接口形式的访问。相对来讲,使用 HTTP Client 调用也很简单。

但 spring-data-elasticsearch 能够更快的支持构建在 Spring 应用上,好比在 application.properties 配置 ES 节点信息和 spring-boot-starter-data-elasticsearch 依赖,直接在 Spring Boot 应用上使用。

我也写了点系列博客在:https://www.bysocket.com/?tag=elasticsearch

还有不少组件没法一一介绍了,好比经常使用的 Redis 作缓存操做等。

3、生产指标监控 Actuator

Starter 组件 Actuator 提供了生产级监控的特性,可使用 Actuator 来监控应用的一切。

使用方式也很简单,加入对应的依赖,而后访问各个 HTTP 请求就能够获取须要的信息。具体提供的信息有:

 

autoconfig    自动配置相关信息 beans            Spring 容器中的 Bean 相关信息 configprops     配置项信息 dump            当前线程信息 env                当前环境变量信息 health            应用的健康信息 info            应用基本信息 metrics            性能指标信息 mappings        请求路径信息 trace            请求调用信息

至于可视化的话,可使用 http/ssh/telnet 等方式拉监控数据到可视化 UI 上便可。进一步可使用 prometheus 采集 springboot  应用指标,用 Grafana 可视化监控数据。

这里我师弟写一遍教程不错:http://www.jianshu.com/p/7ecb57a3f326

4、内嵌式容器 Tomcat / Jetty / Undertow

Spring Boot 运行的应用是独立的一个 Jar 应用,实际上在运行时启动了应用内部的内嵌容器,容器初始化 Spring 环境及其组件并启动应用。

但咱们也能够自定义配置 内嵌式容器,好比将 Tomcat 换成 Jetty。Spring Boot 能这样工做,主要靠下面两点:自动配置和外化配置。

自动配置

Spring Boot 在不须要任何配置状况下,就直接能够运行一个应用。实际上,Spring Boot 框架的 spring-boot-autoconfigure 依赖作了不少默认的配置项,即应用默认值。这种模式叫作 “自动配置”。

Spring Boot 自动配置会根据添加的依赖,自动加载依赖相关的配置属性并启动依赖。例如,默认用的内嵌式容器是 Tomcat ,端口默认设置为 8080。

外化配置

Spring Boot 简化了配置,在 application.properties 文件配置经常使用的应用属性。Spring Boot 能够将配置外部化,这种模式叫作 “外化配置”。

将配置从代码中分离外置,最明显的做用是只要简单地修改下外化配置文件,就能够在不一样环境中,能够运行相同的应用代码。

因此,Spring Boot 启动应用,默认状况下是自动启动了内嵌容器 Tomcat,而且自动设置了默认端口为 8080。

另外还提供了对 Jetty、Undertow 等容器的支持。开发者自行在添加对应的容器 Starter 组件依赖,便可配置并使用对应内嵌容器实例。具体操做以下:

第一步,将 tomcat 依赖排除:

 

<dependency>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-starter-web</artifactId>    <exclusions>        <exclusion>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-tomcat</artifactId>        </exclusion>    </exclusions> </dependency>

spring-boot-starter-web 依赖默认使用 Tomcat 做为内嵌容器

第二步,加入对应的 jetty 依赖(这里也能够是 Undertow 依赖)

 

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

上面大体介绍了 Spring Boot 2.0 有的那些特性,也就是那些事,最后入门介绍下 WebFlux。

5、Spring 5 & Spring WebFlux

最后,Spring Boot 2.0 支持 Spring 5,Spring 5 具备了强大的特性:WebFlux/Reactor。因此最后来聊聊 WebFlux ,就算入个门吧。

对照下 Spring Web MVC ,Spring Web MVC 是基于 Servlet API 和 Servlet 容器设计的。那么 Spring WebFlux 确定不是基于前面二者,它基于 Reactive Streams API  和 Servlet 3.1+ 容器设计。

那 Reactive Streams API 是什么?

先理解 Stream 流是什么?流是序列,是生产者生产,一个或多个消费者消费的元素序列。这种具体的设计模式成为发布订阅模式。常见的流处理机制是 pull / push 模式。背压是一种经常使用策略,使得发布者拥有无限制的缓冲区存储 item,用于确保发布者发布 item 太快时,不会去压制订阅者。

Reactive Streams (响应式流)是提供处理非阻塞背压异步流的一种标准。主要针对的场景是运行时环境(包括 JVM 和 JS)和网络。一样,JDK 9 java.util.concurrent 包提供了两个主要的 API 来处理响应流:

  • Flow

  • SubmissionPublisher

     

为啥只能运行在 Servlet 3.1+ 容器?

你们知道,3.1 规范其中一个新特性是异步处理支持。

异步处理支持:Servlet 线程不需一直阻塞,即不须要到业务处理完毕再输出响应,而后结束 Servlet线程。

异步处理的做用是在接收到请求以后,Servlet 线程能够将耗时的操做委派给另外一个线程来完成,在不生成响应的状况下返回至容器。

主要应用场景是针对业务处理较耗时的状况,能够减小服务器资源的占用,而且提升并发处理速度。

因此 WebFlux 支持的容器有 Tomcat、Jetty(Non-Blocking IO API) ,也能够像 Netty 和 Undertow 的自己就支持异步容器。在容器中 Spring WebFlux 会将输入流适配成 Mono 或者 Flux 格式进行统一处理。

Spring WebFlux 是什么

0?wx_fmt=png

先看这张图,上面咱们了解了容器、响应流。这里介绍下 Spring WebFlux 是什么? Spring WebFlux 是 Spring 5 的一个新模块,包含了响应式 HTTP 和 WebSocket 的支持,另外在上层服务端支持两种不一样的编程模型:

  • 基于 Spring MVC 注解 @Controller 等

  • 基于 Functional 函数式路由

下面是两个实现小案例,首先在 pom.xml 加入对应的依赖:

 

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

基于 Spring MVC 注解 RESTful API

官方案例很简单,以下:

 

@RestController public class PersonController {        private final PersonRepository repository;        public PersonController(PersonRepository repository) {                this.repository = repository;        }        @PostMapping("/person")        Mono<Void> create(@RequestBody Publisher<Person> personStream) {                return this.repository.save(personStream).then();        }        @GetMapping("/person")        Flux<Person> list() {                return this.repository.findAll();        }        @GetMapping("/person/{id}")        Mono<Person> findById(@PathVariable String id) {                return this.repository.findOne(id);        } }

可是 PersonRepository 这种 Spring Data Reactive Repositories 不支持 MySQL,进一步也不支持 MySQL 事务。因此用了 Reactivey 原来的 spring 事务管理就很差用了。

jdbc jpa 的事务是基于阻塞 IO 模型的,若是 Spring Data Reactive  没有升级 IO 模型去支持 JDBC,生产上的应用只能使用不强依赖事务的。

也可使用透明的事务管理,即每次操做的时候以回调形式去传递数据库链接 connection。

Spring Data Reactive Repositories  目前支持 Mongo、Cassandra、Redis、Couchbase 。

若是应用只能使用不强依赖数据事务,依旧使用 MySQL ,可使用下面的实现,代码以下:

 

@RestController @RequestMapping(value = "/city") public class CityRestController {    @Autowired    private CityService cityService;    @RequestMapping(value = "/{id}", method = RequestMethod.GET)    public Mono<City> findOneCity(@PathVariable("id") Long id) {        return Mono.create(cityMonoSink -> cityMonoSink.success(cityService.findCityById(id)));    }    @RequestMapping(method = RequestMethod.GET)    public Flux<City> findAllCity() {        return Flux.create(cityFluxSink -> {            cityService.findAllCity().forEach(city -> {                cityFluxSink.next(city);            });            cityFluxSink.complete();        });    }    @RequestMapping(method = RequestMethod.POST)    public Mono<Long> createCity(@RequestBody City city) {        return Mono.create(cityMonoSink -> cityMonoSink.success(cityService.saveCity(city)));    }    @RequestMapping(method = RequestMethod.PUT)    public Mono<Long> modifyCity(@RequestBody City city) {        return Mono.create(cityMonoSink -> cityMonoSink.success(cityService.updateCity(city)));    }    @RequestMapping(value = "/{id}", method = RequestMethod.DELETE)    public Mono<Long> modifyCity(@PathVariable("id") Long id) {        return Mono.create(cityMonoSink -> cityMonoSink.success(cityService.deleteCity(id)));    } }

findAllCity 方法中,利用 Flux.create 方法对响应进行建立封装成 Flux 数据。而且使用 lambda 写数据流的处理函数会十分的方便。

Service 层依旧是之前那套逻辑,业务服务层接口以下:

 

public interface CityService {    /**     * 获取城市信息列表     *     * @return     */    List<City> findAllCity();    /**     * 根据城市 ID,查询城市信息     *     * @param id     * @return     */    City findCityById(Long id);    /**     * 新增城市信息     *     * @param city     * @return     */    Long saveCity(City city);    /**     * 更新城市信息     *     * @param city     * @return     */    Long updateCity(City city);    /**     * 根据城市 ID,删除城市信息     *     * @param id     * @return     */    Long deleteCity(Long id); }

具体案例在个人 Github:https://github.com/JeffLi1993/springboot-learning-example

基于 Functional 函数式路由实现 RESTful API

建立一个 Route 类来定义 RESTful HTTP 路由:

 

import static org.springframework.web.reactive.function.server.RequestPredicates.GET; import static org.springframework.web.reactive.function.server.RequestPredicates.accept; import static org.springframework.web.reactive.function.server.RouterFunctions.route; @Configuration public class Routes {    private CityService cityService;    public Routes(CityService cityService) {        this.cityService = cityService;    }    @Bean    public RouterFunction<?> routerFunction() {        return route(                       GET("/api/city").and(accept(MediaType.APPLICATION_JSON)), cityService:: findAllCity).and(route(                       GET("/api/user/{id}").and(accept(MediaType.APPLICATION_JSON)), cityService:: findCityById)                );    } }

RoouterFunction 相似 Spring Web MVC 的 @RequestMapping ,用来定义路由信息,每一个路由会映射到一个处理方法,当接受 HTTP 请求时候会调用该处理方法。

建立 HttpServerConfig 自定义 Http Server,这里建立一个 Netty HTTP 服务器:

 

import org.springframework.http.server.reactive.HttpHandler; import org.springframework.http.server.reactive.ReactorHttpHandlerAdapter; import reactor.ipc.netty.http.server.HttpServer; @Configuration public class HttpServerConfig {    @Autowired    private Environment environment;    @Bean    public HttpServer httpServer(RouterFunction<?> routerFunction) {        HttpHandler httpHandler = RouterFunctions.toHttpHandler(routerFunction);        ReactorHttpHandlerAdapter adapter = new ReactorHttpHandlerAdapter(httpHandler);        HttpServer server = HttpServer.create("localhost", Integer.valueOf(environment.getProperty("server.port")));        server.newHandler(adapter);        return server;    } }

天然推荐 Netty 来运行 Reactive 应用,由于 Netty 是基于异步和事件驱动的。

从案例中,你们也简单入门了解 WebFlux

小结

谢谢你们的阅读,本文写的不是那么精致。期待过几天和你们微信沟通交流学习。

by the way , 最近在写一本小小书,《Spring Boot 2.x 核心技术实战(上)基础篇》,针对基础实践,精致地写了 demo 和讲解。

最后仍是谢谢。

 

http://blog.csdn.net/GitChat/article/details/78454120

相关文章
相关标签/搜索