How to properly implement a binder?

一曲冷凌霜 提交于 2019-12-11 17:36:11

问题


Question was heavily edited during discussion with Oleg

I'm trying to implement a binder for BigQuery in Spring Cloud Stream.

Full code of application is avaiable on GitHub.

So far, I've written a BigQueryBinderConfiguration class which returns a BigQueryBinder the following way

@Configuration @EnableConfigurationProperties({ BigQueryConfiguration.class })
public class BigQueryBinderConfiguration {
    @Autowired BigQueryConfiguration configuration;

    @Bean
    BigQueryBinder bigQueryMessageChannelBinder(BigQueryConfiguration configuration, BigQueryProvisioningProvider provisioningProvider) {

        return new BigQueryBinder(configuration, provisioningProvider);
    }

    @Bean BigQueryProvisioningProvider provisioningProvider() {
        return new BigQueryProvisioningProvider(configuration);
    }
}

My problem is that when doing so, my other binders (Rabbit and Kafka) are no more recognized.

My testing protocol is as follows : I start my application and check in rabbitmq admin interface if my application registers as a consumer. This is not the case when this code is uncommented.

When debugging call to bigQueryMessageChannelBinder(....), I observe the following things.

The DefaultBinderFactory#getBinder(...) method always return my BigQueryBinder instance. Debugging indicates that the call to this.context.getBeansOfType(Binder.class); returns a list that only contains my BigQueryBinder. I'm puzzled, because the other binders are in my classpath, and if I remove the factory method BigQueryBinderConfiguration#bigQueryMessageChannelBinder(....), everything works fine.

I've discovered during debug that DefaultBinderFactory is the class that is used to associate a binder to a configuration name. I've also discovered that Binder implementations should not appear in Map<String, Binder> binders. But unfortunatly, my Binder implementation appear in that list. i guess it has something to do with the bean nature. But how ?


回答1:


I think the best thing you can do is to first look at our new TestChannelBinder.java. Basically it's a full blown binder backed by Spring Integration. In other words Spring Integration and it's channels play a role of a message broker the same was Rabbit, Kafka, GCP and other binders. What's important about this binder is that it effectively demonstrates a bare minimum of what's required to implement a functioning binder.




回答2:


Based on the conversations in this issue #1623 .

I want to consume/produce messages from/to Spring Cloud Stream channels to an internal event bus from Axon Framework.

Is the model in this photo correct?

Application model with internal and external binder

If it is correct,I think we should use the channels from Stream in custom binder by injecting beans or other methods.

In TestChannelBinder class the channels have been created in user code with calling constructor,How to use channels managed by Spring Cloud Stream in custom binder?

private SubscribableChannel provisionDestination(String name, boolean pubSub) {
        String destinationName = name + ".destination";
        SubscribableChannel destination = this.provisionedDestinations
                .get(destinationName);
        if (destination == null) {
            destination = pubSub ? new PublishSubscribeChannel() : new DirectChannel();
            ((AbstractMessageChannel) destination).setBeanName(destinationName);
            ((AbstractMessageChannel) destination).setComponentName(destinationName);
            this.provisionedDestinations.put(destinationName, destination);
        }
        return destination;
    }


来源:https://stackoverflow.com/questions/54921839/how-to-properly-implement-a-binder

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!