codecamp

SpringCloud 使用动态绑定的目的地

除了使用@EnableBinding定义的通道外,Spring Cloud Stream还允许应用程序将消息发送到动态绑定的目的地。例如,当需要在运行时确定目标目的地时,这很有用。应用程序可以通过使用@EnableBinding注释自动注册的BinderAwareChannelResolver bean来实现。

“ spring.cloud.stream.dynamicDestinations”属性可用于将动态目标名称限制为已知集合(白名单)。如果未设置此属性,则可以动态绑定任何目标。

BinderAwareChannelResolver可以直接使用,如以下使用路径变量来确定目标通道的REST控制器示例所示:

@EnableBinding
@Controller
public class SourceWithDynamicDestination {

    @Autowired
    private BinderAwareChannelResolver resolver;

    @RequestMapping(path = "/{target}", method = POST, consumes = "*/*")
    @ResponseStatus(HttpStatus.ACCEPTED)
    public void handleRequest(@RequestBody String body, @PathVariable("target") target,
           @RequestHeader(HttpHeaders.CONTENT_TYPE) Object contentType) {
        sendMessage(body, target, contentType);
    }

    private void sendMessage(String body, String target, Object contentType) {
        resolver.resolveDestination(target).send(MessageBuilder.createMessage(body,
                new MessageHeaders(Collections.singletonMap(MessageHeaders.CONTENT_TYPE, contentType))));
    }
}

现在考虑当我们在默认端口(8080)上启动应用程序并使用CURL发出以下请求时会发生什么:

curl -H "Content-Type: application/json" -X POST -d "customer-1" http://localhost:8080/customers

curl -H "Content-Type: application/json" -X POST -d "order-1" http://localhost:8080/orders

在经纪人中创建目的地“客户”和“订单”(交换为Rabbit或在主题为“ Kafka”中),名称为“客户”和“订单”,数据为发布到适当的目的地。

BinderAwareChannelResolver是通用的Spring Integration DestinationResolver,并且可以注入到其他组件中,例如,在路由器中使用基于传入的target字段的SpEL表达式的路由器JSON消息。以下示例包含一个读取SpEL表达式的路由器:

@EnableBinding
@Controller
public class SourceWithDynamicDestination {

    @Autowired
    private BinderAwareChannelResolver resolver;


    @RequestMapping(path = "/", method = POST, consumes = "application/json")
    @ResponseStatus(HttpStatus.ACCEPTED)
    public void handleRequest(@RequestBody String body, @RequestHeader(HttpHeaders.CONTENT_TYPE) Object contentType) {
        sendMessage(body, contentType);
    }

    private void sendMessage(Object body, Object contentType) {
        routerChannel().send(MessageBuilder.createMessage(body,
                new MessageHeaders(Collections.singletonMap(MessageHeaders.CONTENT_TYPE, contentType))));
    }

    @Bean(name = "routerChannel")
    public MessageChannel routerChannel() {
        return new DirectChannel();
    }

    @Bean
    @ServiceActivator(inputChannel = "routerChannel")
    public ExpressionEvaluatingRouter router() {
        ExpressionEvaluatingRouter router =
            new ExpressionEvaluatingRouter(new SpelExpressionParser().parseExpression("payload.target"));
        router.setDefaultOutputChannelName("default-output");
        router.setChannelResolver(resolver);
        return router;
    }
}

路由器接收器应用程序使用此技术的按需创建的目的地。

如果预先知道通道名称,则可以像其他任何目的地一样配置生产者属性。或者,如果您注册NewBindingCallback<> bean,则会在创建绑定之前调用它。回调采用绑定程序使用的扩展生产者属性的通用类型。它有一种方法:

void configure(String channelName, MessageChannel channel, ProducerProperties producerProperties,
        T extendedProducerProperties);

下面的示例显示如何使用RabbitMQ活页夹:

@Bean
public NewBindingCallback<RabbitProducerProperties> dynamicConfigurer() {
    return (name, channel, props, extended) -> {
        props.setRequiredGroups("bindThisQueue");
        extended.setQueueNameGroupOnly(true);
        extended.setAutoBindDlq(true);
        extended.setDeadLetterQueueName("myDLQ");
    };
}
如果需要支持具有多个活页夹类型的动态目标,请对通用类型使用Object,并根据需要强制转换extended参数。
SpringCloud 生产者Properties
SpringCloud 机械学
温馨提示
下载编程狮App,免费阅读超1000+编程语言教程
取消
确定
目录

三、Spring Cloud Netflix

SpringCloud Hystrix超时和Ribbon客户

SpringCloud 重试失败的请求

五、Spring Cloud Stream

六、SpringCloud Binder实现

SpringCloud 重试RabbitMQ Binder

SpringCloud Dead-Letter队列处理

八、Spring Cloud Sleuth

SpringCloud 当前Span

十二、Spring Cloud for Cloud Foundry

十三、Spring Cloud Contract

Spring Cloud Contract验证程序设置

SrpingCloud Gradle项目

十五、Spring Cloud网关

Spring Cloud 配置路由谓词工厂和网关过滤工厂

Spring Cloud TLS / SSL

Spring Cloud网关配置

SpringCloud 故障排除

十八、Spring Cloud GCP

Spring Cloud GCP Spring资源

Spring Cloud Spring JDBC

Spring Cloud Redis的Cloud Memorystore

Spring Cloud 云身份识别代理(IAP)身份验证

关闭

MIP.setData({ 'pageTheme' : getCookie('pageTheme') || {'day':true, 'night':false}, 'pageFontSize' : getCookie('pageFontSize') || 20 }); MIP.watch('pageTheme', function(newValue){ setCookie('pageTheme', JSON.stringify(newValue)) }); MIP.watch('pageFontSize', function(newValue){ setCookie('pageFontSize', newValue) }); function setCookie(name, value){ var days = 1; var exp = new Date(); exp.setTime(exp.getTime() + days*24*60*60*1000); document.cookie = name + '=' + value + ';expires=' + exp.toUTCString(); } function getCookie(name){ var reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)'); return document.cookie.match(reg) ? JSON.parse(document.cookie.match(reg)[2]) : null; }