likes
comments
collection
share

响应式编程springwebFlux与koltin

作者站长头像
站长
· 阅读数 4

响应式编程与kotlin

提示:经过自己的学习和理解想分享和记录一下,如有错误,请指正 第一章:为什么选择响应式编程以及kotlin


介绍

在下本为一名javaer,奈何为讨生计,被迫加入kotlin大军(哈哈哈,开玩笑)因为公司从java转到kotlin并且已经稳定运行很久了,然后我做为新人进入公司从java到kotlin的一个改变,在学习代码和熟悉公司代码的流程中,有许许多多的问题和相关理解不到的地方。先点题吧:公司由java变成了kotln为后端语言,spring一套,然后web框架从传统的spring mvc变成了spring webFlux,数据库由mysql变成了PostgreSQL,还有太多太多辣,目前先介绍这几个,然后谈一下为什么改变吧。


本篇解释权归本人所有,如有任何不对的地方望指正

一、官方概念到处都有,我直接谈理解上干货

接下来我会从四个方面为你一一道来!当然目前只针对后端开发!

1.同步编程

有一个接口test,从请求打进来,传统的编码方式是从上往下依次调用直至方法结束,那么如果在中途,有大文件的io(阻塞),亦或是大量数据库的网络io(阻塞),此时需要等待这些请求完成过后才能往下依次顺序执行,这叫同步调用,同时是阻塞的 响应式编程springwebFlux与koltin

2.多线程编程

从接口进来的线程叫主线程,你开了一个线程a去执行sql数据库的相关操作,开了第二个线程b去执行大文件io的相关操作,主线程依然执行自己的同步方法,这叫多线程,那么如果主线程的任务执行的很快且接下来的操作需要等待线程a,线程b的结果继续执行,主线程是不是就在这等待了!那么主线程啥事都没干,在这干等着,是不是干等!是不是浪费资源了! 响应式编程springwebFlux与koltin

3.异步编程

异步编程和多线程编程其实很像,但是又一点都不像,像在哪他们都要开启其他的线程去执行,但是呢,主线程一旦执行完成后,不会等待你子线程的执行是否结束了,主线程会被安排去执行其它事情,等到两个子线程完成任务后他们会主动通知其他线程来接手继续执行方法里未完成的任务直至结束,那么这里,主线程是不是没有干等着,是不是没有造成资源浪费。但是这里可能有人要说了,线程切换上下文会消耗更多的资源,那么这就是cpu和算法的问题了,我又不用关心。 响应式编程springwebFlux与koltin

响应式编程

响应式编程其实就是异步编程,大家所认为的异步和真正实际意义上的异步编程有着很大的区别,异步并不是说开一个多线程就叫异步了,异步在我的理解里面可以说是资源的最大利用!

那么响应式编程为什么就是异步编程,响应式的概念为一个订阅者,一个发布者,以及一个管道 姑且我们这样认为,在一个请求里,用户为订阅者,我们的接口会发布者,接口里的业务逻辑处理的方法为管道,而响应式做到的是什么,是异步,是资源的最大利用,那么为什么有了异步编程,还要写一个响应式框架呢?因为大量的异步回调代码可读性极低,难以理解,还是那句回调地狱,所以响应式编程就是在异步编程的基础之上进行了封装和设计,我们只需要对事件本身进行处理,无需关心回调,意思就是你就像平常写同步阻塞代码一样,无需去关心他什么时候回调的。

二、搭建一个kotlin-springWebFlux项目Gradle版本

在实验之前,大家要自行先学习一下suspend函数以及kotlin协程!如果对相关有兴趣的话,可以私信我做一些简单教程!

1.引入依赖

代码如下(示例):

val kotlin_version: String by project
val logback_version: String by project

plugins {
    kotlin("jvm") version "1.9.20"
    id("org.springframework.boot") version "3.1.2"
    id("io.spring.dependency-management") version "1.1.2"
    kotlin("plugin.spring") version "1.9.10" // The Kotlin Spring plugin
}


group = "mrone.com"
version = "0.0.1"


repositories {
    mavenCentral()
}

dependencies {
    implementation("org.springframework.boot:spring-boot-starter-webflux")
    implementation ("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2")
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor")
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactive")
    implementation("com.squareup.okhttp3:okhttp:3.14.9")
    implementation("io.projectreactor.kotlin:reactor-kotlin-extensions")
    implementation("org.jetbrains.kotlin:kotlin-reflect")


}

2.测试代码

接口函数被suspend函数修饰

代码如下(示例): 响应式编程springwebFlux与koltin

从执行器中可以看出,当我开启GlobalScope.async去执行一个事件时,主线程并没有被挂起,这里WebFlux可以看出主线程是由reactor+nio的线程池里分配的线程来执行主要事件,但由于函数被suspend方法给修饰了,所以这里我们能够看出来我们并不需要去定义Reactor相关的Mono以及Flux数据流,当我们将suspend将方法进行修饰时,我们的接口做为发布者publisher,接口里面的相关业务处理就是数据流,WebFlux会自动将suspend修饰的方法的返回值封装为Mono或者是FLux数据流,其次用户调用接口,调用方则做为订阅者订阅需要的数据。 那么之前到理解就没有问题,为什么,首先,因为suspend修饰函数时,只有在协程域中调用它才会被挂起,否则会被阻塞住,当然我们这里只调用了一个方法,并在里面执行,但实际上也能够看到,suspend里面的方法会有一个主协程域在执行for500的循环,而开启的新异步协程会执行for1000的循环,两者互不干扰,为异步非阻塞。

没有被suspend函数修饰的呢

响应式编程springwebFlux与koltin

如图:报错400,请求错误,但是实际上应该是返回类型错误,修改一下代码看看 响应式编程springwebFlux与koltin

可以看到成功返回了,Mono返回的是0-1个对象,而Flux返回的是个列表,其实不用理解的太复杂,因为Reactor需要两端,而做为web开发也是两端,client and server,客户端发起请求,服务端响应请求,只是做为WebFlux需要对其进行数据修饰为响应数据流,而不能是普通流,所以为了方便开发以及避免更加繁琐的去处理数据,而去专注相关业务,直接使用suspend修饰,同样一点只有suspend函数里才能调用其他suspend函数,刚好又能实现无线套娃。


总结

响应式编程以后肯定会是更加主流的一种开发方式,因为网民的增加和数据量的提升,想要更好的体验以及更高性能的方式去获取数据,响应式是一个很好的选择!目前也在逐步摸索和学习阶段

需要demo请留言!!

联系我

@一字先生个人所有

联系方式CSDN:Xsed

哔哩哔哩:一字先生

gitee:gitee.com/catchforyou

github: github.com/CaseOfShe/

网易邮箱:mr_onei@163.com