当前位置: 首页 > 知识库问答 >
问题:

spring webflux如何在反应式世界中管理顺序业务逻辑代码

奚高扬
2023-03-14

这种方法对反应友好吗?

我有一个反应式控制器“save”方法调用myService。保存(请求)。

服务层需要:

  1. jdbc save(在另一个调度程序上,因为代码被阻塞),

我无法在一个管道中链接所有调用,或者我不知道如何实现这一点,因为我想尽快发送回(1)丢失的......

相反,我触发(1)中的子运算。

这是我应该如何处理这件事,还是有一个聪明的方法可以在一个管道中做到这一点?

下面的代码来支持这个问题。谢谢。

控制器层调用的服务

    public Mono<Prospect> save(final Prospect prospect) {

    return Mono.fromCallable(
            () -> {
                Prospect savedProspect = transactionTemplate.execute(status -> prospectRepository.save(prospect));

                templateService.generateProspectSubscription(savedProspect)
                        .map(t ->
                                EmailPostRequest.builder()
                                       ...
                                        .build())
                        .flatMap(emailService::send)
                        .subscribe();

                return savedProspect;
            })
            .subscribeOn(jdbcScheduler);

}

模板服务

public Mono<String> generateProspectSubscription(final Prospect prospect) {        
    return Mono.fromCallable(
            () -> {
                Map<String, Object> model = new HashMap<>();
               ...

                Template t = freemarkerConfig.getTemplate(WELCOME_EN_FTL);
                String html = FreeMarkerTemplateUtils.processTemplateIntoString(t, model);
                return html;
            }
    ).subscribeOn(freemarkerScheduler);
}

电子邮件服务

 public Mono<Void> send(final EmailPostRequest e) {

    return Mono.fromCallable(
            () -> {
                MimeMessage message = emailSender.createMimeMessage();
                MimeMessageHelper mimeHelper = new MimeMessageHelper(message,
                        MimeMessageHelper.MULTIPART_MODE_MIXED_RELATED,
                        StandardCharsets.UTF_8.name());


                mimeHelper.setTo(e.getTo());
                mimeHelper.setText(e.getText(), true);
                mimeHelper.setSubject(e.getSubject());
                mimeHelper.setFrom(new InternetAddress(e.getFrom(), e.getPersonal()));

                emailSender.send(message);

                return Mono.empty();
            }
    ).subscribeOn(emailScheduler).then();
}

编辑的服务我认为这个版本的服务层更干净,但任何意见都是赞赏的

    public Mono<Prospect> save(final Prospect prospect) {

    return Mono.fromCallable(
            () -> transactionTemplate.execute(status -> prospectRepository.save(prospect)))
            .subscribeOn(jdbcScheduler)
            .flatMap(savedProspect -> {
                        templateService.generateProspectSubscription(savedProspect)
                                .map(t ->
                                        EmailPostRequest.builder()
                                                ...
                                                .build())
                                .flatMap(emailService::send)
                                .subscribe();

                        return Mono.just(savedProspect);
                    }
            );
}

共有1个答案

鱼宜
2023-03-14

这种方法不是反应友好的,因为您正在百分之百地包装阻塞库。在这个用例中,您无法真正看到反应式运行时的好处,很可能应用程序的性能比阻塞式运行时差。

如果您的主要动机是性能,那么这可能会适得其反。将大量阻塞I/O工作转移到专门的Schedulers会在内存(创建更多线程)和CPU(上下文切换)方面产生运行时成本。如果性能和可扩展性是您主要关心的问题,那么切换到Spring MVC并利用Flux/Mono支持它,或者甚至调用block()运算符可能更合适。

如果您的主要动机是使用特定的库,例如Spring Framework的WebClient和Spring MVC,那么您最好使用。block()运算符,而不是包装和调度所有内容。

 类似资料:
  • 我正在编写一个向Android手机发送通知的反应式api。发送通知的过程需要从手机访问令牌代码以将消息推送给它。为了实现这一点,我在服务器端创建了一个endpoint来接收来自手机的令牌。我的问题是保存令牌,然后在上面描述的过程中使用它。这是TokenController、TokenService、TokenRepository和Token POJO: 为了发送通知,我有一个通知控制器,需要访问数

  • 我正在使用SpringWebSockets,我想从存储库返回一个项目列表 我怎么能在WebSocket会话中发送此列表 这是如何将项目列表发送到websocket的处理程序方法

  • 综述 在多功能的动态web应用程序中测试业务逻辑漏洞需要用非常规手段来思考。如果应用认证机制原先以1、2、3的步骤依次执行的验证身份目的来开发,万一用户从步骤1直接跳到步骤3会发生什么?用更加简单的例子来说,在打开失败、权限拒绝或仅仅500的错误的情况下,应用程序是否依然能够提供访问权限? 可以举出许多例子,但是不变的思想是“跳出常规思维”。这种类型的漏洞无法被漏洞扫描工具探测到,依赖于渗透测试人

  • 我正在做一个WSDL的申请。但实际上我不明白是什么使“呢?wsdl”参数以及我将如何处理返回的XML。例如: https://adwords.google.com/api/adwords/cm/v201309/CampaignService?wsdl 这个URL返回和XML字符串,但我该怎么办? 我可以使用jaxb(xjc)将模式文件转换为java类,但我不明白如何正确使用此WSDL? 感谢您的回

  • 我有一个Spring批处理应用程序。我的Spring批处理应用程序由两个步骤组成。 提取csv数据,添加到记录tbl 提取记录tbl行,根据数据验证解析到Food tbl。 步骤2使用微线程完成 我需要处理记录行tbl,无论是否验证,当前日期时间都会添加回记录行 a.验证失败,DateTime错误代码也将添加到记录行中 b.通过验证,日期时间添加到记录行中。Row也将添加到食品tbl中。 在步骤2

  • 1.1  概述 业务逻辑模块主要用于编写业务逻辑,一般包含三个子模块:action(定义action和procedure)、code(业务逻辑的实现,一般使用java实现,有src,dsrc,lib)、fn(函数定义)。 1.2  Action定义 语法: <action name=" n" global="true" log-enabled="true" procedure=" "> <参