WebFlux初尝试

前言

WebFlux是Spring5.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也会提醒你的

相关推荐
LHICOD1 小时前
Linux-2
java·linux·后端·jar·vmware·svm·vm
小杨互联网1 小时前
Go 现代 CLI 工具离线镜像合集
开发语言·后端·golang·开源·go·命令行
lazy H1 小时前
【计算机网络】第 15 篇:Java BIO、NIO 与高并发网络通信——从 Socket 理解 I/O 模型
网络·后端·tcp/ip·计算机网络·nio·408
geovindu1 小时前
rust: Semaphore Pattern
开发语言·后端·设计模式·rust·代理模式·企业级信号量模式·同步型模式
CoderYanger3 小时前
Java EE 进阶:5. Spring IoC&DI(第三弹):Spring DI
java·开发语言·spring boot·spring·面试·java-ee·mvc
Thneonl3 小时前
Claude Code 频繁 Compacting?发布次日我根治了 2 个痛点
后端·rust
郭小李3 小时前
spring中@Transactional注解对事务的支持
数据库·spring·oracle
环境栈笔记4 小时前
指纹浏览器安卓怎么用?从运行位置到功能验收,先把三种方案分清
前端·人工智能·后端·自动化
小小张说故事5 小时前
Python 的 list 为什么能装下任何类型?拆开 PyObject* 数组,以及它让你多付了多少内存
后端·python
小蒜学长5 小时前
基于SpringBoot 框架的自媒体新闻系统的设计与实现(代码+数据库+LW)
java·spring boot·后端·mysql数据库·自媒体新闻管理系统