Search code examples
spring-bootibm-mqspring-jmsspring-integration-dsl

Migrating from Spring Boot 2 to 3


I am migrating an integration flow from Spring Boot 2 to 3. I have code that runs with Spring Boot 2 as follows :

@Bean
public BroadcastCapableChannel jmsSubscribeChannel() {
    return Jms.publishSubscribeChannel(connectionFactory)
        .destination(inTopic)
        .get();
}

I've tried to do the following :

@Bean
public BroadcastCapableChannel jmsSubscribeChannel() {
    return Jms.publishSubscribeChannel(connectionFactory)
        .destination(inTopic)
        .getObject();
}

But the documentation for getObject() states the following :

This method must not be called from the target configuration

Any other method which I try does not match the return signature of the method and I can't find a method that would return the correct object.

So I wanted to know if there is a guide on how the code should be modified going from spring-boot 2 to 3.


Solution

  • According to the new documentation :
    ( https://docs.spring.io/spring-integration/reference/dsl/java-subflows.html )
    Starting with version 5.3, a BroadcastCapableChannel-based publishSubscribeChannel() implementation is provided to configure sub-flow subscribers on broker-backed message channels. For example, we now can configure several subscribers as sub-flows on the Jms.publishSubscribeChannel()

    So essentially the code goes from :

    @Bean
    public BroadcastCapableChannel jmsSubscribeChannel() {
        return Jms.publishSubscribeChannel(connectionFactory)
            .destination(inTopic)
            .get();
    }
    
    @Bean
    public IntegrationFlow pubSubFlow() {
        return f -> f
                .publishSubscribeChannel(jmsPublishSubscribeChannel(),
                        pubsub -> pubsub
                                .subscribe(subFlow -> subFlow
                                    .channel(c -> c.queue("jmsPubSubBridgeChannel1")))
                                .subscribe(subFlow -> subFlow
                                    .channel(c -> c.queue("jmsPubSubBridgeChannel2"))));
    }
    

    To :

    @Bean
    public JmsPublishSubscribeMessageChannelSpec jmsPublishSubscribeChannel() {
        return Jms.publishSubscribeChannel(jmsConnectionFactory())
                    .destination("pubsub");
    }
    
    @Bean
    public IntegrationFlow pubSubFlow(BroadcastCapableChannel jmsPublishSubscribeChannel) {
        return f -> f
                .publishSubscribeChannel(jmsPublishSubscribeChannel,
                        pubsub -> pubsub
                                .subscribe(subFlow -> subFlow
                                    .channel(c -> c.queue("jmsPubSubBridgeChannel1")))
                                .subscribe(subFlow -> subFlow
                                    .channel(c -> c.queue("jmsPubSubBridgeChannel2"))));
    }
    

    i.e. You create a spec, then use the spec