WebFlux初尝试

前言

WebFluxSpring5.0推出的基于Reactor响应式模型的MVC框架,目前在国内相关的使用和资料比较少,本栏目主要分享一些使用过程中的经验,帮助大家入门并熟练使用这种响应式模型的编程方式。

开始

JDK我使用的是17,大家也可以升级下自己远古版本1.8了

引入依赖

xml 复制代码
 
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.2.3</version>
</parent>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-webflux</artifactId>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <scope>annotationProcessor</scope>
    </dependency>
</dependencies>

最简单的依赖就能启动项目

Hello World 环节

和Spring MVC并没有太大的差异,返回值用Mono Wrap一下

java 复制代码
@RestController
public class TestController {

    @GetMapping("/hello")
    public Mono<String> hello() {
        return Mono.just("hello world");
    }

}

Run

启动项目 , 打印这条日志恭喜成功

Netty started on port 8080

shell 复制代码
curl http://127.0.0.1:8080/hello

hello world

Why

SpringApplication.run(Application.class, args)创造世界

java 复制代码
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
		this.resourceLoader = resourceLoader;
		Assert.notNull(primarySources, "PrimarySources must not be null");
		this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
            // 看这里,从classpath推导出springboot web环境
		this.webApplicationType = WebApplicationType.deduceFromClasspath();
		this.bootstrapRegistryInitializers = new ArrayList<>(
				getSpringFactoriesInstances(BootstrapRegistryInitializer.class));
		setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
		setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
		this.mainApplicationClass = deduceMainApplicationClass();
	}
java 复制代码
   private static final String WEBMVC_INDICATOR_CLASS = "org.springframework.web.servlet.DispatcherServlet";

	private static final String WEBFLUX_INDICATOR_CLASS = "org.springframework.web.reactive.DispatcherHandler";

	private static final String JERSEY_INDICATOR_CLASS = "org.glassfish.jersey.servlet.ServletContainer";

	static WebApplicationType deduceFromClasspath() {
        // 在这判断,如果是reactive环境就会启动响应式的容器
		if (ClassUtils.isPresent(WEBFLUX_INDICATOR_CLASS, null) && !ClassUtils.isPresent(WEBMVC_INDICATOR_CLASS, null)
				&& !ClassUtils.isPresent(JERSEY_INDICATOR_CLASS, null)) {
			return WebApplicationType.REACTIVE;
		}
		for (String className : SERVLET_INDICATOR_CLASSES) {
			if (!ClassUtils.isPresent(className, null)) {
				return WebApplicationType.NONE;
			}
		}
		return WebApplicationType.SERVLET;
	}

Mono与Flux

响应式中一个数据也能看为信号 Mono.just("hello world")可以看为发了一个信号,而Flux则是用来发送多个信号,比如Flux.just("1", "2", "3"),初学者可以简单粗暴的理解为List类型。

通常来说响应式是需要我们进行消费的,不然一切都是白搭,比如

java 复制代码
Mono.just("hello world")
.subscribe(s -> System.out.println(s));

但是Demo中我们并没有消费,因为webflux框架已经帮我们消费了

我们在自己写定时任务之类的操作中一定记得主动消费!!!

java 复制代码
@Scheduled(fixedRateString = "5000")
public void scheduled() {
    Mono.just("hello world")
            .subscribe();
}

这只是简单的示例,实际中很可能是处理数据库数据、Redis数据等任务。

重要,前面的不看这个必须看!

Reactor模型是调度少量的线程来处理更多的任务,和我们以往的性能到底瓶颈就增加线程池的操作很不一样,所有在响应式的世界里禁止阻塞,这非常重要将严重影响你系统的吞吐量。

以前阻塞式编程的做法是,100个工人每个工人负责一个事情,忙不过来了就加到200个人。

响应式的处理是,只分配10个工人,每个工人通过一个总的调度来处理多个事情,比如1个人工人有10袋水泥,现在只需要把1袋搬上车就可以忙其他事情,等车运完这袋水泥回来再搬1袋,阻塞就相当于这个工人只能在这守着直到10袋水泥都搬运完。

所以求求你们千万不要在代码里.block();除非你单独开一个线程池来处理。

Idea也会提醒你的

相关推荐
无名指的等待71233 分钟前
SpringBoot中使用ElasticSearch
java·spring boot·后端
Tatakai251 小时前
Mybatis Plus分页查询返回total为0问题
java·spring·bug·mybatis
.生产的驴1 小时前
SpringBoot 消息队列RabbitMQ 消费者确认机制 失败重试机制
java·spring boot·分布式·后端·rabbitmq·java-rabbitmq
AskHarries2 小时前
Spring Boot利用dag加速Spring beans初始化
java·spring boot·后端
苹果酱05672 小时前
一文读懂SpringCLoud
java·开发语言·spring boot·后端·中间件
掐指一算乀缺钱2 小时前
SpringBoot 数据库表结构文档生成
java·数据库·spring boot·后端·spring
飞翔的佩奇3 小时前
xxl-job适配sqlite本地数据库及mysql数据库。可根据配置指定使用哪种数据库。
数据库·spring boot·mysql·sqlite·xxl-job·任务调度
bug菌¹3 小时前
滚雪球学SpringCloud[4.2讲]: Zuul:Netflix API Gateway详解
spring·spring cloud·gateway
小哇6663 小时前
spring-TransactionTemplate 编程式事务
数据库·spring
计算机学姐5 小时前
基于python+django+vue的影视推荐系统
开发语言·vue.js·后端·python·mysql·django·intellij-idea