NagelAufnKopp
NagelAufnKopp

Reputation: 35

Springs "@MessagingGateway" annotation on external interfaces

I am about to migrate a project created with an old version of Spring (using XML config) to Spring Boot (using Java config). The project is using Spring Integration for communication via JMS and AMQP. As far as I understood, I have to replace the

<int:gateway id="someID" service-interface="MyMessageGateway" 
 default-request-channel="myRequestChannel" 
 default-reply-channel="myResponseChannel" 
 default-reply-timeout="20000" />

with

@MessagingGateway(name="someID", defaultRequestChannel = "myRequestChannel",
defaultReplyChannel = "myResponseChannel", defaultReplyTimeout = "20000")
public interface MyMessageGateway{ ...... }

My problem is, that the interface, that is in use now, is placed in a library I can't access.

How can I define this Interface as my MessagingGateway?

Thanks in advance!

Upvotes: 1

Views: 6347

Answers (2)

Artem Bilan
Artem Bilan

Reputation: 121177

I have just tested this trick:

interface IControlBusGateway {

    void send(String command);
}

@MessagingGateway(defaultRequestChannel = "controlBus")
interface ControlBusGateway extends IControlBusGateway {

}

...


@Autowired
private IControlBusGateway controlBus;

...

try {
        this.bridgeFlow2Input.send(message);
        fail("Expected MessageDispatchingException");
    }
    catch (Exception e) {
        assertThat(e, instanceOf(MessageDeliveryException.class));
        assertThat(e.getCause(), instanceOf(MessageDispatchingException.class));
        assertThat(e.getMessage(), containsString("Dispatcher has no subscribers"));
    }
    this.controlBus.send("@bridge.start()");
    this.bridgeFlow2Input.send(message);
    reply = this.bridgeFlow2Output.receive(5000);
    assertNotNull(reply);

In other words you can just extends that external interface to your local one. The GatewayProxyFactoryBean will do the proxy magic for you underneath.

Also we have this JIRA for similar use-case: https://jira.spring.io/browse/INT-4134

Upvotes: 3

Gary Russell
Gary Russell

Reputation: 174494

Use a GatewayProxyFactoryBean; here's a simple example:

@SpringBootApplication
public class So41162166Application {

    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(So41162166Application.class, args);
        context.getBean(NoAnnotationsAllowed.class).foo("foo");
        context.close();
    }

    @Bean
    public GatewayProxyFactoryBean gateway() {
        GatewayProxyFactoryBean gateway = new GatewayProxyFactoryBean(NoAnnotationsAllowed.class);
        gateway.setDefaultRequestChannel(channel());
        return gateway;
    }

    @Bean
    public MessageChannel channel() {
        return new DirectChannel();
    }

    @ServiceActivator(inputChannel = "channel")
    public void out(String foo) {
        System.out.println(foo);
    }

    public static interface NoAnnotationsAllowed {

        public void foo(String out);

    }

}

Upvotes: 2

Related Questions