小编roh*_*hit的帖子

带有强制参数的 Lombok 构建器

如果我将@Builder 添加到一个类中。构建器方法已创建。

Person.builder().name("john").surname("Smith").build();
Run Code Online (Sandbox Code Playgroud)

我有一个要求,其中特定字段是强制性的。在这种情况下,名称字段是必需的。理想情况下,我想这样声明。

Person.builder("john").surname("Smith").build();
Run Code Online (Sandbox Code Playgroud)

在谷歌搜索时,我发现了许多替代方案,例如覆盖构建器实现,如下所示:

@Builder
public class Person {

    private String name;
    private String surname;

    public static PersonBuilder builder(String name) {
        return new PersonBuilder().name(name);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后像下面这样使用它:

Person p = Person.builder("Name").surname("Surname").build();
Run Code Online (Sandbox Code Playgroud)

上述方法的问题在于它仍然提供如下所示的 name() 和 PersonBuilder() 方法,这是我不想要的:

Person p = Person.builder("Name").surname("Surname").name("").build();
Run Code Online (Sandbox Code Playgroud)
Person p = new Person.PersonBuilder().build;
Run Code Online (Sandbox Code Playgroud)

另一种方法是在 name 处添加 @lombok.nonnull 检查,这将强制在创建对象时为 name 提供值。但它是一个运行时检查。它不会强迫我在创建对象时为 name 提供值。

lombok 是否提供了任何其他技术来实现以下目标:

 Person p = Person.builder("Name").surname("Surname").build();
Run Code Online (Sandbox Code Playgroud)

注意: builder() 和 name() 不应暴露。创建 Person 对象的唯一方法应该在上方或下方:

 Person p = Person.builder("Name").build();
Run Code Online (Sandbox Code Playgroud)

java builder lombok

8
推荐指数
1
解决办法
1278
查看次数

如何使用反应器有条件地重复或重试

我使用 SpringBoot 和 Webflux 进行反应式编程。我想重复该服务,直到数据可用(除了 null 之外还返回一些内容)

\n

我有一个将一些数据插入数据库的服务,并且有第二个服务消耗该数据。\n我想继续从第二个服务查询数据库,直到数据可用。下面的代码我试图使用 Project Reactor 来实现这一点:

\n
Mono<SubscriptionQueryResult<App, App>> subscriptionQuery = reactiveQueryGateway\n.subscriptionQuery(new FindAppByIdQuery(appId), ResponseTypes.instanceOf(App.class), ResponseTypes.instanceOf(App.class));\n\nsubscriptionQuery\n  .filter(a -> Objects.nonNull(a.initialResult().block()))\n  .repeatWhen(Repeat.onlyIf(repeatContext -> true)\n  .exponentialBackoff(Duration.ofMillis(100), Duration.ofSeconds(100))\n  .timeout(Duration.ofSeconds(30))).subscribe();\n
Run Code Online (Sandbox Code Playgroud)\n

在执行此操作时,我遇到以下异常:

\n
reactor.core.Exceptions$ErrorCallbackNotImplemented: java.lang.IllegalStateException: block()/blockFirst()/blockLast() are blocking, which is not supported in thread parallel-1\n
Run Code Online (Sandbox Code Playgroud)\n

在浏览 webflux 文档时,我发现在 Reactor 线程中调用 block() 函数是不可能的。这样的尝试会导致上述错误:

\n

为了克服这个问题,我尝试了以下方法:

\n
subscriptionQuery\n .flatMap(a -> a.initialResult())\n .filter(a -> Objects.nonNull(a))\n .repeatWhen(Repeat.onlyIf(repeatContext -> true)\n .exponentialBackoff(Duration.ofMillis(100), Duration.ofSeconds(100))\n .timeout(Duration.ofSeconds(30)))\n .subscribe();\n
Run Code Online (Sandbox Code Playgroud)\n

但它没有给我想要的结果,我想我错过了一些东西。任何人都可以建议实现这一目标的正确方法。

\n

谢谢。

\n

repeat reactor axon project-reactor spring-webflux

5
推荐指数
1
解决办法
3353
查看次数

跨服务共享轴突查询

我正在运行三个不同的服务(A、B 和 C),并且所有服务都连接到 axonserver 4.3.3。除此之外,我还有一个 api 服务,其中包含所有事件,以便可以在所有服务之间共享。当一个事件被触发时(假设由服务 A 触发),其他服务(B 和 C)正在监听该事件,并且它们会做出相应的反应。

现在我也想共享查询,这样当一个服务(比如说A)想要一些属于另一个服务(比如说B)的信息时,它可以直接触发相应的查询,该查询将由服务B侦听并返回信息。

  1. axon 中是否允许(即,在服务之间共享查询,就像我们对事件所做的那样)?
  2. 如果允许,它是否遵循轴突最佳实践?
  3. 如果不允许/不遵循最佳实践,替代解决方案是什么?

更新

我只是将查询添加到 common-api 服务并从服务 A 中触发它,如下所示:

  1. 当我使用时queryGateway.query( findCourierByIdQuery, responseType):我得到了 queryhandler not found 异常
  2. 当我使用时queryGateway.subscriptionQuery( findCourierByIdQuery, initialResponseType, updateResponseType):我什么也没得到
  3. 当我使用时queryGateway.scatterGather( findCourierByIdQuery, responseType, timeout, timeUnit):我有一个空流

当我从服务 B 本身触发 findCourierByIdQuery 时,查询处理程序被调用并且我得到了正确的响应。

我的观察是,只有当查询从同一组件(本例中为服务 B)触发时,查询处理程序才会被调用,如果我从其他组件(服务 A)触发查询,则不会被调用。

请注意,所有服务都独立运行在不同的主机和端口上,但连接到同一个 axonserver,并且 queryhandler 编写在服务 B 中。

所以基本上实现是这样的:

  • findCourierByIdQuery 在公共 api 服务中定义。
  • 服务A和B有公共api服务的依赖。
  • 服务 A 执行 findCourierByIdQuery 的查询。
  • 服务 B 具有 findCourierByIdQuery 查询处理程序实现。

java axon spring-boot

2
推荐指数
1
解决办法
468
查看次数