@Override
  public Binding<MessageChannel> bindProducer(
      final String name, MessageChannel moduleOutputChannel, Properties properties) {
    Assert.isInstanceOf(SubscribableChannel.class, moduleOutputChannel);
    KafkaPropertiesAccessor producerPropertiesAccessor = new KafkaPropertiesAccessor(properties);
    validateProducerProperties(name, properties, SUPPORTED_PRODUCER_PROPERTIES);
    if (logger.isInfoEnabled()) {
      logger.info("Using kafka topic for outbound: " + name);
    }

    final String topicName = escapeTopicName(name);

    int numPartitions = producerPropertiesAccessor.getNumberOfKafkaPartitionsForProducer();

    Collection<Partition> partitions =
        ensureTopicCreated(topicName, numPartitions, defaultReplicationFactor);

    ProducerMetadata<byte[], byte[]> producerMetadata =
        new ProducerMetadata<>(
            topicName, byte[].class, byte[].class, BYTE_ARRAY_SERIALIZER, BYTE_ARRAY_SERIALIZER);
    producerMetadata.setCompressionType(
        ProducerMetadata.CompressionType.valueOf(
            producerPropertiesAccessor.getCompressionCodec(this.defaultCompressionCodec)));
    producerMetadata.setBatchBytes(producerPropertiesAccessor.getBatchSize(this.defaultBatchSize));
    Properties additionalProps = new Properties();
    additionalProps.put(
        ProducerConfig.ACKS_CONFIG,
        String.valueOf(producerPropertiesAccessor.getRequiredAcks(this.defaultRequiredAcks)));
    additionalProps.put(
        ProducerConfig.LINGER_MS_CONFIG,
        String.valueOf(producerPropertiesAccessor.getBatchTimeout(this.defaultBatchTimeout)));
    ProducerFactoryBean<byte[], byte[]> producerFB =
        new ProducerFactoryBean<>(producerMetadata, brokers, additionalProps);

    try {
      final ProducerConfiguration<byte[], byte[]> producerConfiguration =
          new ProducerConfiguration<>(producerMetadata, producerFB.getObject());

      MessageHandler handler =
          new SendingHandler(
              topicName, producerPropertiesAccessor, partitions.size(), producerConfiguration);
      EventDrivenConsumer consumer =
          new EventDrivenConsumer((SubscribableChannel) moduleOutputChannel, handler);
      consumer.setBeanFactory(this.getBeanFactory());
      consumer.setBeanName("outbound." + name);
      consumer.afterPropertiesSet();
      Binding<MessageChannel> producerBinding =
          Binding.forProducer(name, moduleOutputChannel, consumer, producerPropertiesAccessor);
      addBinding(producerBinding);
      producerBinding.start();
      return producerBinding;
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
  }
 private void doRegisterProducer(
     final String name,
     MessageChannel moduleOutputChannel,
     AmqpOutboundEndpoint delegate,
     String replyTo,
     RabbitPropertiesAccessor properties) {
   Assert.isInstanceOf(SubscribableChannel.class, moduleOutputChannel);
   MessageHandler handler = new SendingHandler(delegate, replyTo, properties);
   EventDrivenConsumer consumer =
       new EventDrivenConsumer((SubscribableChannel) moduleOutputChannel, handler);
   consumer.setBeanFactory(getBeanFactory());
   consumer.setBeanName("outbound." + name);
   consumer.afterPropertiesSet();
   Binding producerBinding = Binding.forProducer(name, moduleOutputChannel, consumer, properties);
   addBinding(producerBinding);
   producerBinding.start();
 }