千家信息网

如何分析springboot响应式编程整合webFlux的问题

发表于:2025-01-20 作者:千家信息网编辑
千家信息网最后更新 2025年01月20日,这期内容当中小编将会给大家带来有关如何分析springboot响应式编程整合webFlux的问题,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。在servlet3.0
千家信息网最后更新 2025年01月20日如何分析springboot响应式编程整合webFlux的问题

这期内容当中小编将会给大家带来有关如何分析springboot响应式编程整合webFlux的问题,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。

在servlet3.0标准之前,是每一个请求对应一个线程。如果此时一个线程出现了高延迟,就会产生阻塞问题,从而导致整个服务出现严重的性能情况,因为一旦要调用第三方接口,就有可能出现这样的操作了。早期的处理方式只能是手工控制线程。

在servlet3.0标准之后,为了解决此类问题,所以提供了异步响应的支持。在异步响应处理结构中,可以将耗时操作的部分交由一个专属的异步线程进行响应处理,同时请求的线程资源将被释放,并将该线程返回到线程池中,以供其他用户使用,这样的操作机制将极大的提升程序的并发性能。

对于以上给出的响应式编程支持,仅仅是一些原生的支持模式,而现在既然基于springboot程序开发,那么就需要考虑一些更简单的整合。

而在spring中实现响应式编程,那么则需要使用到spring webFlux,该组件是一个重新构建的且基于Reactive Streams标准实现的异步非阻塞Web开发框架,以Reactor开发框架为基础,可以更加容易实现高并发访问下的请求处理模型。在springboot2.x版本中提供了webFlux依赖模块,该模块有两种模型实现:一种是基于功能性端点的方式,另一种是基于SpringMVC注解方式。

Maven引入

    org.springframework.boot    spring-boot-starter-webflux

整合处理器:

package com.example.oldguy.myWebFlux.handler; import com.example.oldguy.myVo.Message;import lombok.extern.slf4j.Slf4j;import org.springframework.stereotype.Component;import reactor.core.publisher.Mono;@Component@Slf4jpublic class MessageHandler {    public Mono echoHandler(Message message){        log.info("【{}】业务层接收处理数据:{}",Thread.currentThread().getName());        message.setTitle("【】"+Thread.currentThread().getName()+"】"+message.getTitle());        message.setContent("【】"+Thread.currentThread().getName()+"】"+message.getContent());        return Mono.create(item->item.success(message)); //实现数据响应    }}

整合控制器:

package com.example.oldguy.myController; import com.example.oldguy.myVo.Message;import com.example.oldguy.myWebFlux.handler.MessageHandler;import com.example.oldguy.mytask.MyThreadTask;import io.swagger.annotations.Api;import io.swagger.annotations.ApiOperation;import lombok.SneakyThrows;import lombok.extern.slf4j.Slf4j;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;import org.springframework.web.bind.WebDataBinder;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.InitBinder;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import org.springframework.web.context.request.RequestContextHolder;import org.springframework.web.context.request.ServletRequestAttributes;import org.springframework.web.context.request.async.DeferredResult;import javax.servlet.http.HttpServletRequest;import java.beans.PropertyEditorSupport;import java.time.Instant;import java.time.LocalDate;import java.time.ZoneId;import java.time.format.DateTimeFormatter;import java.util.Date;import java.util.concurrent.TimeUnit;/** * 异步线程的处理机制 */@RestController@RequestMapping("/message/*")@Slf4j@Api(tags = "异步处理")public class AsyncController {    @Autowired    private ThreadPoolTaskExecutor threadPoolTaskExecutor;    private MyThreadTask task;    private MessageHandler messageHandler;    /**     * 日期转换     * @param     * @return     */    private static final DateTimeFormatter LOCAL_DATE_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd");    @InitBinder    public void initBinder(WebDataBinder binder){        binder.registerCustomEditor(Date.class,new PropertyEditorSupport(){            @Override            public void setAsText(String text) throws IllegalArgumentException {                LocalDate localDate = LocalDate.parse(text,LOCAL_DATE_FORMAT);                Instant instant = localDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant();                super.setValue(Date.from(instant));            }        });    }    @GetMapping("runnable")    @ApiOperation("异常处理Runnable")    public Object message(String message) {        log.info("外部线程:{}", Thread.currentThread().getName());        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();        DeferredResult result = new DeferredResult<>(6000L); //设置异步响应        this.threadPoolTaskExecutor.execute(new Runnable() { //线程核心任务            @SneakyThrows            public void run() {                log.info("内部线程:{}",Thread.currentThread().getName());                TimeUnit.SECONDS.sleep(7);                result.setResult("[echo]"+message); //执行最终的响应        result.onCompletion(new Runnable() { //完成处理线程                log.info("完成线程:{}",Thread.currentThread().getName()); //日志输出        result.onTimeout(new Runnable() {                log.info("超时线程:{}",Thread.currentThread().getName());                result.setResult("【请求超时】"+request.getRequestURI()); //超时路径        return  result;    @GetMapping("task")    @ApiOperation("task异步任务开启")    public Object messageTask(String message){        log.info("外部线程{}",Thread.currentThread().getName());        this.task.startTaskHander();        return "【echo】"+message;    @GetMapping("webflux")    @ApiOperation("整合webflux")    public Object echo(Message message){        log.info("接收用户信息,用户方发送的参数为message={}",message);        return this.messageHandler.echoHandler(message);}

页面响应:

控制台响应:

2021-11-30 15:04:06.946 INFO 22884 --- [nio-1999-exec-1] c.e.oldguy.myController.AsyncController : 接收用户信息,用户方发送的参数为message=Message(title=pansd, pubdate=Tue Nov 30 00:00:00 CST 2021, content=come on baby)
2021-11-30 15:04:06.947 INFO 22884 --- [nio-1999-exec-1] c.e.o.myWebFlux.handler.MessageHandler : 【http-nio-1999-exec-1】业务层接收处理数据:Message(title=pansd, pubdate=Tue Nov 30 00:00:00 CST 2021, content=come on baby)

webFlux响应map和List

//webFlux响应集合    public Flux list(Message message){        List messageList = new ArrayList<>();        for(int i=0;i<10;i++){            Message m = new Message();            m.setTitle(i+"--"+message.getTitle());            m.setContent(i+"--"+message.getContent());            m.setPubdate(message.getPubdate());            messageList.add(m);        }        return Flux.fromIterable(messageList);    }    public Flux> map(Message message){        Map map = new HashMap<>();        for(int i=0;i<10;i++){            Message m = new Message();            m.setTitle(i+"--"+message.getTitle());            m.setContent(i+"--"+message.getContent());            m.setPubdate(message.getPubdate());            map.put("pansd-"+i,m);        }//        Set> entries = map.entrySet();        return Flux.fromIterable(map.entrySet());    }
@GetMapping("webfluxList")@ApiOperation("整合webfluxList")public Object echoList(Message message){    log.info("接收用户信息,用户方发送的参数为message={}",message);    return this.messageHandler.list(message);} @GetMapping("webfluxMap")@ApiOperation("整合webfluxMap")public Object echoMap(Message message){    log.info("接收用户信息,用户方发送的参数为message={}",message);    return this.messageHandler.map(message);}

上述就是小编为大家分享的如何分析springboot响应式编程整合webFlux的问题了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注行业资讯频道。

线程 处理 用户 整合 问题 分析 编程 信息 参数 数据 方式 标准 开发 控制 支持 业务 任务 内容 性能 机制 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 软件开发和游戏开发一样吗 系统数据库安全管理办法 软件开发 制度 标准 体系 服务器新增共享文件 孝义网络安全科 长沙编译分布式存储服务器 虚拟机架设ftp服务器 怎么进服务器管理员模式语句 网络安全人员能力认证通过率 和平精英换服务器怎么不显示了 做兼职网软件开发 企业网络安全答题 无线网络安全防护策略 数据库查询所有学生平均分 数据库登不上怎么回事 福建视频云空间功能服务器 数据库 人工智能算法 世界全网络技术有限公司 工商软件开发质量保证 江苏数据库安全箱定制价格 如何在数据库中存储分类信息 网络安全控制软件 浅谈怎么学习网络技术 服务器备份怎么关机 ai与网络安全哪个好 服务器对外提供了哪些资源 产品软件开发怎么制定计划 有诚信的软件开发培训 广播电视网络安全等级保护定级 网络设备服务器是什么会计科目
0