消息驱动:Spring Cloud Stream

1.stream 配置中的含义

当我们使用默认group,和destination时默认创建名为input 的持久化的topic类型的exchange。


队列是一个destination前缀然后一个随你名称的自动删除队列。



现在我们自定义group,destination。如下。

spring.cloud.stream.bindings.input.group=queueName
spring.cloud.stream.bindings.input.destination=exchangeName

根据destination,帮我们创建了一个持久化的topic类型的exchange。




根据group,帮我们创建了一个持久化的queue。


总结:对于RabbitMQ,destination 对应的是exchange,group对应的是queue(带有前缀)。对于kafka,destination 对应的是Topic,group就是对应的消费group。对于一个应用集群,如果不需要重复消费消息,必须定义group,否则不必定义group(比如刷新配置消息)。


2.发送消息

1.定义通道,通道名为mqScoreOutput
spring.cloud.stream.bindings.mqScoreOutput.destination=exchangeName2
2.定义接口
public interface SendChannel {

    String SCORE_OUPUT = "mqScoreOutput";

    @Output(SendChannel.SCORE_OUPUT)
    MessageChannel scoreOutput();
}
3.进行绑定
@EnableBinding(SendChannel.class)
public class SendServerConfig {

}
4.注入可以发送消息的bean
@Service
public class SendServer {

    @Autowired
    private SendChannel sendChannel;

    @Autowired
    private MessageChannel mqScoreOutput;

    public void send1() {
        Message<String> fffff = MessageBuilder.withPayload("fffffsend1").build();
        sendChannel.scoreOutput().send(fffff);
        System.out.println("发送消息send1");
    }

    public void send2() {
        Message<String> fffff = MessageBuilder.withPayload("fffffsend2").build();
        mqScoreOutput.send(fffff);
        System.out.println("发送消息send2");
    }
}

3.接收消息

1.定义通道
spring.cloud.stream.bindings.mqScoreInput.group=queueName2
spring.cloud.stream.bindings.mqScoreInput.destination=exchangeName2
2.定义接口
public interface ReceiverChannel {

    String SCORE_INPUT = "mqScoreInput";

    @Input(ReceiverChannel.SCORE_INPUT)
    SubscribableChannel scoreInput();
}
3.进行绑定
@EnableBinding({ReceiverChannel.class})
public class ReceiverServerConfig {

    @StreamListener(ReceiverChannel.SCORE_INPUT)
    public void receive(Object object) {
        System.out.println(object);
    }
}

4.注意事项

接收消息通道和发送消息通道名不可以重复。即使destination一样。例如:
spring.cloud.stream.bindings.mqScoreInput.group=queueName2
spring.cloud.stream.bindings.mqScoreInput.destination=exchangeName2

spring.cloud.stream.bindings.mqScoreOutput.destination=exchangeName2
我们不用mqScoreOutput 这个通道名,发送消息的时候也用mqScoreInput.
public interface SendChannel {

    String SCORE_OUPUT = "mqScoreInput";

    @Output(SendChannel.SCORE_OUPUT)
    @Qualifier("mqScoreOutput")
    MessageChannel scoreOutput();
}

接收消息的时候报如下错误。
Caused by: org.springframework.integration.MessageDispatchingException: Dispatcher has no subscribers

5.Spring Integration 原生支持接收消息

1.定义通道
spring.cloud.stream.bindings.mq1.group=queueName
spring.cloud.stream.bindings.mq1.destination=exchangeName
2.定义接口
public interface ReceiverChannel2 {
    String INPUT = "mq1";

    @Input(INPUT)
    SubscribableChannel input();
}
3.进行绑定
@EnableBinding({ReceiverChannel2.class})
public class ReceiverServerConfig2 {


    @ServiceActivator(inputChannel = ReceiverChannel2.INPUT)
    public void receive(Object object) {
        System.out.println(object);
    }
}

6.消息转换

1.配置contentType类型
spring.cloud.stream.bindings.mqScoreInput.group=queueName2
spring.cloud.stream.bindings.mqScoreInput.destination=exchangeName2
spring.cloud.stream.bindings.mqScoreInput.contentType=application/json

spring.cloud.stream.bindings.mqScoreOutput.destination=exchangeName2
spring.cloud.stream.bindings.mqScoreOutput.contentType=application/json
2.发送对象
@Service
public class SendServer {

    @Autowired
    private SendChannel sendChannel;

    @Autowired
    @Qualifier("mqScoreOutput")
    private MessageChannel mqScoreOutput;

    public void send1() {
        User u = new User();
        u.setId(1L);
        u.setName("fffffsend1");
        Message<User> fffff = MessageBuilder.withPayload(u).build();
        sendChannel.scoreOutput().send(fffff);
        System.out.println("发送消息send1");
    }

    public void send2() {
        User u = new User();
        u.setId(2L);
        u.setName("fffffsend2");
        Message<User> fffff = MessageBuilder.withPayload(u).build();
        mqScoreOutput.send(fffff);
        System.out.println("发送消息send2");
    }
}
3.接收对象
@EnableBinding({ReceiverChannel.class})
public class ReceiverServerConfig {

    @StreamListener(ReceiverChannel.SCORE_INPUT)
    public void receive(User user) {
        System.out.println(user);
    }
}

7.消息反馈

@EnableBinding({ReceiverChannel.class})
public class ReceiverServerConfig {

    @StreamListener(ReceiverChannel.SCORE_INPUT)
    @SendTo(SendServer2.SendChannel2.OUTPUT)
    public Object receive(User user) {
        user.setId(5555L);
        return user;
    }
}
使用SendTo 指定通道即可。

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值