spring cloud stream 3.0 -- 生产者消费者例子

spring cloud stream 3.0 的开发方式有了比较大的变化,不需要注解,根据方法名自动生成需要的队列和exchange。

创建项目

使用 Spring Initializr创建一个新project,并选择上依赖“Cloud Stream"。
选择rabbitmq作为broker。

依赖:

<dependency>
	<groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-stream-rabbit</artifactId>
</dependency>

rabbit地址

application.yml:

spring:
  rabbitmq:
    addresses: localhost:5672

编写消费者代码

@SpringBootApplication
public class LoggingConsumerApplication {

	public static void main(String[] args) {
		SpringApplication.run(LoggingConsumerApplication.class, args);
	}

	@Bean
	public Consumer<Person> log() {
	    return person -> {
	        System.out.println("Received: " + person);
	    };
	}

	public static class Person {
		private String name;
		public String getName() {
			return name;
		}
		public void setName(String name) {
			this.name = name;
		}
		public String toString() {
			return this.name;
		}
	}
}

上面的代码做了以下的事情:

  1. 通过Consumer接口实现了一个简单的消费者。
  2. spring框架自动帮我们把消息者绑定到了destination名为log-in-0,随机的group名
  3. spring框架自动帮我们把消息转换为Persion对象。

运行

输出:

2020-11-09 16:31:17.105  INFO 6296 --- [           main] c.s.b.r.p.RabbitExchangeQueueProvisioner : declaring queue for inbound: log-in-0.anonymous.pMOQQi6eQPiJ46nMCp3LuA, bound to: log-in-0
2020-11-09 16:31:17.106  INFO 6296 --- [           main] o.s.a.r.c.CachingConnectionFactory       : Attempting to connect to: [192.168.1.57, 192.168.1.58:5672]
2020-11-09 16:31:17.133  INFO 6296 --- [           main] o.s.a.r.c.CachingConnectionFactory       : Created new connection: rabbitConnectionFactory#10ef5fa0:0/SimpleConnection@7ae0cc89 [delegate=amqp://guest@192.168.1.57:5672/, localPort= 63722]
2020-11-09 16:31:17.206  INFO 6296 --- [           main] o.s.c.stream.binder.BinderErrorChannel   : Channel 'log-in-0.anonymous.pMOQQi6eQPiJ46nMCp3LuA.errors' has 1 subscriber(s).
2020-11-09 16:31:17.206  INFO 6296 --- [           main] o.s.c.stream.binder.BinderErrorChannel   : Channel 'log-in-0.anonymous.pMOQQi6eQPiJ46nMCp3LuA.errors' has 2 subscriber(s).
2020-11-09 16:31:17.219  INFO 6296 --- [           main] o.s.i.a.i.AmqpInboundChannelAdapter      : started bean 'inbound.log-in-0.anonymous.pMOQQi6eQPiJ46nMCp3LuA'
2020-11-09 16:31:17.230  INFO 6296 --- [           main] com.example.demo.DemoApplication         : Started DemoApplication in 2.749 seconds (JVM running for 3.593)

上面的输出中有队列名。anonymous.pMOQQi6eQPiJ46nMCp3LuA是自动生成的group名。设置spring.cloud.stream.bindings.log-in-0.group=hello可以得到一个固定的队列名log-in-0.hello

注意:
指定group名称后,创建的队列不再会自动删除。

到rabbitmq的管理页面,发送下面的消息到队列log-in-0.anonymous.pMOQQi6eQPiJ46nMCp3LuA

{"name":"Sam Spade"}

程序控制台会有输出:

Received: Sam Spade

生产者

同步发送消息


@SpringBootApplication
@Controller
public class DemoApplication {

    @Autowired
    private StreamBridge streamBridge;

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
    @RequestMapping
    @ResponseStatus(HttpStatus.ACCEPTED)
    public void delegateToSupplier(@RequestBody String body) {
        System.out.println("Sending " + body);
        streamBridge.send("log-in-0", body);
    }
}

上面的例子通过StreamBridge发送消息到log-in-0,与之前的消息者的destination对应。

发送post请求到http://localhost:8080

curl -H "Content-Type: text/plain" -X POST -d '{"name":"Sam Spade"}' http://localhost:8080/

前面定义的消费者会收到消息。

也可以通过配置属性spring.cloud.stream.bindings.log-in-0.destination=des来自定义destination名称。

Reactive异步发送消息

@SpringBootApplication
@Controller
public class DemoApplication {

    EmitterProcessor<String> processor = EmitterProcessor.create();


    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
    @RequestMapping
    @ResponseStatus(HttpStatus.ACCEPTED)
    public void delegateToSupplier(@RequestBody String body) {
        processor.onNext(body);
    }

    @Bean
    public Supplier<Flux<String>> supplier() {
        return () -> this.processor;
    }

通过配置spring.cloud.stream.bindings.supplier-out-0.destination=des指定要发送到的destination。

注意:
如果项目中有多个Supplier或Consumer,需要通过配置spring.cloud.function.definition=log;supplier指定哪些方法需要绑定。

binding命名规则

上面代码中的binding名称都是自动生成的,命名规则是:

  • input - <functionName> + -in- + <index>
  • output - <functionName> + -out- + <index>

Supplier为output,Consumer为input。除非方法有多个input或output,否则index为0。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xiegwei

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值