|
对于最新稳定版本,请使用spring-cloud-stream 5.0.1! |
处理(在发送消息之后)
一旦函数被调用,其结果将由框架发送到目标目的地,从而完成函数调用周期。
然而,尽管此循环可能已完成,但从商业角度来看,直到完成此循环后执行某些其他任务,才可能完全完成。
当这种需求出现时,可以像本帖所述那样通过组合使用0和1来解决这个问题。但从4.0.3版本开始,框架提供了更自然的方法来通过Spring Cloud Function项目提供的3来解决此问题。5是一个特殊的半标记函数,它包含一个名为6的方法,用于提供实现此类后处理任务的位置。
package org.springframework.cloud.function.context
. . .
public interface PostProcessingFunction<I, O> extends Function<I, O> {
default void postProcess(Message<O> result) {
}
}
那么,现在您有两个选项。
选项1:您可以将函数实现为PostProcessingFunction,并通过实现其postProcess(Message>)方法来包含额外的后期处理行为。
private static class Uppercase implements PostProcessingFunction<String, String> {
@Override
public String apply(String input) {
return input.toUpperCase();
}
@Override
public void postProcess(Message<String> result) {
System.out.println("Function Uppercase has been successfully invoked and its result successfully sent to target destination");
}
}
. . .
@Bean
public Function<String, String> uppercase() {
return new Uppercase();
}
选项二:如果您已经有一个现有的函数,并且不希望更改其实现方式或希望将您的函数保持为POJO,您可以简单地仅实现postProcess(Message>)方法,并将此新的后期处理函数与其他函数组合。
private static class Logger implements PostProcessingFunction<?, String> {
@Override
public void postProcess(Message<String> result) {
System.out.println("Function has been successfully invoked and its result successfully sent to target destination");
}
}
. . .
@Bean
public Function<String, String> uppercase() {
return v -> v.toUpperCase();
}
@Bean
public Function<String, String> logger() {
return new Logger();
}
. . .
// and then have your function definition as such `uppercase|logger`
注意:
在函数组合的情况下,如果存在PostProcessingFunction(即最后出现的实例),则只有该实例会生效。例如,假设有以下函数定义 - foo|bar|baz 和 foo 都是PostProcessingFunction的实例,则只会调用baz.postProcess(Message>)。
如果baz不是PostProcessingFunction的实例,则不会执行任何后期处理功能。
有人可能会争辩说,你可以通过函数组合轻松地做到这一点,只需将后处理器作为另一个Function进行组合。这确实是一种可能性,但是在此情况下,后处理功能将在上一个函数调用之后、消息发送到目标目的地之前立即被调用,也就是在函数调用周期完成之前。