外部接口上的 Springs“@MessagingGateway”注解

Springs "@MessagingGateway" annotation on external interfaces

我打算将使用旧版本 Spring(使用 XML 配置)创建的项目迁移到 Spring 引导(使用 Java 配置)。 该项目正在使用 Spring 集成通过 JMS 和 AMQP 进行通信。据我了解,我必须更换

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

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

我的问题是,现在正在使用的界面放在我无法访问的库中。

如何将此接口定义为我的 MessagingGateway?

提前致谢!

使用GatewayProxyFactoryBean;这是一个简单的例子:

@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);

    }

}

我刚刚测试了这个技巧:

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);

换句话说,您可以 extends 将外部接口连接到本地接口。 GatewayProxyFactoryBean 会在下方为您施展代理魔法。

我们也有类似用例的 JIRA:https://jira.spring.io/browse/INT-4134