3.1之后改用函数式编程,本质是用jdk自己提供的函数来代替了@EnableBinding等注解。
现在有如下三个方法
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
@Configuration
public class Scs_test {
@Bean
public Supplier<String> source(){
return () -> {
System.out.println("from source");
return "hello world";
};
}
@Bean
public Function<String,String> function(){
return msg -> {
System.out.println("from function");
return "add function + "+msg;
};
}
@Bean
public Consumer<String> sink(){
return msg -> {
System.out.println("from sink");
System.out.println(msg);
};
}
}
以及配置文件
server.port=8088
#rabbitmq配置
spring.cloud.stream.binders.rabbit.type=rabbit
spring.cloud.stream.binders.rabbit.environment.spring.rabbitmq.host=localhost
spring.cloud.stream.binders.rabbit.environment.spring.rabbitmq.port=5672
spring.cloud.stream.binders.rabbit.environment.spring.rabbitmq.username=guest
spring.cloud.stream.binders.rabbit.environment.spring.rabbitmq.password=guest
spring.cloud.stream.binders.rabbit.environment.spring.rabbitmq.virtualHost=/
spring.cloud.stream.default-binder=rabbit
#指定应用程序的函数定义的配置项
spring.cloud.function.definition=source;function;sink
#对应source方法
spring.cloud.stream.bindings.source-out-0.destination=test1
#对应function方法
spring.cloud.stream.bindings.function-in-0.destination=test1
spring.cloud.stream.bindings.function-in-0.group=function
spring.cloud.stream.bindings.function-out-0.destination=test2
#对应sink方法
spring.cloud.stream.bindings.sink-in-0.destination=test2
spring.cloud.stream.bindings.sink-in-0.group=sink
Supplier作用是作为信号源不断发送消息。Function<T,R>接收消息,可在方法对消息进行加工后再次转发,其中T为接受消息的类型,R为转发的类型。Consumer只接受消息。
在配置文件中,则要先通过spring.cloud.function.definition来先指定函数的名称,再spring.cloud.stream.bindings对函数进行配置,配置固定格式为(函数名)-in/out-(index),
in对应当前方法的接受,out对应输出;.destination=test1,作用是绑定到rabbitmq中对应的交换机。最好在用于接收端点配置分组如:spring.cloud.stream.bindings.function-in-0.group=function
当执行以上代码时,运行结果就会如此循环下去
同时后台rabbit中也有对应的信息和绑定情况
自定义发送消息
当然实际情况很少用到让系统自动不断地发送消息,而是自定义发送。这时候用到StreamBridge组件。
此时添加一个新的Controller用来给我们访问和发送消息并将之前的source配置文件注释:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.stream.function.StreamBridge;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class SendController {
@Autowired
private StreamBridge streamBridge;
@GetMapping("send/{msg}")
public String sendMsg(@PathVariable String msg){
streamBridge.send("output",msg);
return "send success";
}
}
配置文件
server.port=8088
#rabbitmq配置
spring.cloud.stream.binders.rabbit.type=rabbit
spring.cloud.stream.binders.rabbit.environment.spring.rabbitmq.host=localhost
spring.cloud.stream.binders.rabbit.environment.spring.rabbitmq.port=5672
spring.cloud.stream.binders.rabbit.environment.spring.rabbitmq.username=guest
spring.cloud.stream.binders.rabbit.environment.spring.rabbitmq.password=guest
spring.cloud.stream.binders.rabbit.environment.spring.rabbitmq.virtualHost=/
spring.cloud.stream.default-binder=rabbit
#指定应用程序的函数定义的配置项
spring.cloud.function.definition=function;sink
#对应streamBridge中的BindName的output
spring.cloud.stream.bindings.output.destination=test1
#对应source方法
#spring.cloud.stream.bindings.source-out-0.destination=test1
#对应function方法
spring.cloud.stream.bindings.function-in-0.destination=test1
spring.cloud.stream.bindings.function-in-0.group=function
spring.cloud.stream.bindings.function-out-0.destination=test2
#对应sink方法
spring.cloud.stream.bindings.sink-in-0.destination=test2
spring.cloud.stream.bindings.sink-in-0.group=sink
这里的spring.cloud.stream.bindings.output.destination=test1中的output为streamBridge.send("output",msg);中对应的发送端点名称,配置文件中的.destination=test1同样是将他与名为test1的交换机绑定,如果没有没这句,这样发送消息时就不会。当然如果你现在output改成output-in/out-0也是不行的,因为当以这种格式命名时会将output当做一个函数名,然后系统找不到对应的output函数就会报错。
此时运行后每访问一次
控制台都会打印一组代表数据传递成功。