Search code examples
springspring-bootspring-integration

How to use java Java configuration class in spring integration xml file related to apache kafka?


we are using xml file to implement apache kafka using spring-integration. for now producer and consumer factories are called using @bean in xml file. but I want to read configurations from java class and use that class in the xml file. How do I do that for producer and consumer?

current version for producer:

<int:chain input-channel="kafka-output-channel">
        <int:object-to-json-transformer/>
        <int-kafka:outbound-channel-adapter id="kafkaOutboundChannelAdapter"
                                            kafka-template="template"
                                            topic="${topic.name}" />
    </int:chain>

<bean id="pf" class="org.springframework.kafka.core.DefaultKafkaProducerFactory">
        <constructor-arg>
            <map>
                <entry key="bootstrap.servers" value="${broker.list}" />
                <entry key="key.serializer" value="org.apache.kafka.common.serialization.StringSerializer"/>
                <entry key="value.serializer" value="org.apache.kafka.common.serialization.StringSerializer"/>
            </map>
        </constructor-arg>
    </bean>

<!-- Kafka Template -->
<bean id="template" class="org.springframework.kafka.core.KafkaTemplate">
    <constructor-arg ref="pf"/>
</bean>

But I want to create class like below and use beans below in the xml file,

@Configuration
public class KafkaProducerConfig {
    @Bean
    public KafkaTemplate<String, String> kafkaTemplate() {
        return new KafkaTemplate<>(producerFactory());
    }

    @Bean
    public ProducerFactory<String, String> producerFactory() {
        Map<String, Object> props = new HashMap<>();
        props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, appConfig.getBrokersList());
        props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
        props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
        return new DefaultKafkaProducerFactory<>(props);
    }
}

same thing I want to do for consumer part!

could someone please help?


Solution

  • Nothing is changed here. The XML and Java & Annotation configurations contributes to the same ApplicationContext and bean declared in one place can be references in the other, and wise versa. So, to use that kafkaTemplate bean in the XML, you just need to use exactly this name instead of that template and remove those bean definitions in the XML.

    Only the problem that annotation configuration has to be primary: use an AnnotationConfigApplicationContext. Although I see that you use Spring Boot, so everything is OK. Your XML config has to be used on some @Configuration class as a @ImportResource. On the other hand if you have already enough experience with annotations configuration, there might not be a reason to stick with XML config even for Spring Integration. Consider to investigate Java DSL which smoothly replaces whatever you can have in XML: https://docs.spring.io/spring-integration/docs/current/reference/html/dsl.html#java-dsl

    Please, also pay attention that there is an auto-configuration for Apache Kafka in Spring Boot. So you might not need to configure your template and produce/consumer factories: https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#messaging.kafka