Spring Integration Gateway内部Bean定义

时间:2014-08-15 21:58:21

标签: spring configuration spring-integration

我正在升级:

  • Spring 3.1.0.RELEASE => 4.0.6.RELEASE
  • Spring Integration 2.1.0.RELEASE => 4.0.3.RELEASE

我注意到网关的XML配置与内部bean的一些不兼容性。

在升级之前,这样的事情很好:

<bean id="eventPublisher" class="com.blorp.EventPublisher">
    <constructor-arg>
           <int:gateway default-request-channel="eventPublishingChannel"
                         default-reply-timeout="10000"
                         service-interface="com.blorp.messaging.Sender">
                <int:method name="send" />
            </int:gateway>
    </constructor-arg>
</bean>


<int:channel id="eventPublishingChannel" />

执行上述升级后,当在运行时实际发送事件时,会抛出异常,因为尚未设置请求通道:

Caused by: java.lang.IllegalStateException: send is not supported, because no request channel has been configured
    at org.springframework.util.Assert.state(Assert.java:385) ~[spring-core-4.0.6.RELEASE.jar:4.0.6.RELEASE]
    at org.springframework.integration.gateway.MessagingGatewaySupport.send(MessagingGatewaySupport.java:197) ~[spring-integration-core-4.0.3.RELEASE.jar:na]
    at org.springframework.integration.gateway.GatewayProxyFactoryBean.invokeGatewayMethod(GatewayProxyFactoryBean.java:344) ~[spring-integration-core-4.0.3.RELEASE.jar:na]
    at org.springframework.integration.gateway.GatewayProxyFactoryBean.doInvoke(GatewayProxyFactoryBean.java:304) ~[spring-integration-core-4.0.3.RELEASE.jar:na]
    at org.springframework.integration.gateway.GatewayProxyFactoryBean.invoke(GatewayProxyFactoryBean.java:295) ~[spring-integration-core-4.0.3.RELEASE.jar:na]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.0.6.RELEASE.jar:4.0.6.RELEASE]
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207) ~[spring-aop-4.0.6.RELEASE.jar:4.0.6.RELEASE]
    at com.sun.proxy.$Proxy84.send(Unknown Source) ~[na:na]
    at com.blorp.DefaultEventPublisher.publish(DefaultEventPublisher.java:29) ~[blorp-0.54.0-SNAPSHOT.jar:na]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.7.0_45]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) ~[na:1.7.0_45]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.7.0_45]
    at java.lang.reflect.Method.invoke(Method.java:606) ~[na:1.7.0_45]
...

当我逐步使用调试器时,MessageGatewaySupport.requestChannel属性确实是null,即使配置指定了它。

解决方法是不将网关配置为内部bean。下面的代码段运行良好:

<int:gateway id="sender" default-request-channel="eventPublishingChannel"
                         default-reply-timeout="10000"
                         service-interface="com.blorp.messaging.Sender">
    <int:method name="send" />
</int:gateway>

<bean id="eventPublisher" class="com.blorp.EventPublisher">
    <constructor-arg ref="sender" />
</bean>

我很好奇为什么前者在升级后没有工作。这是创建代理的问题吗?这是一个错误吗?我还没有找到问题。

1 个答案:

答案 0 :(得分:0)

这是真的,因为在这里你尝试将<gateway>配置为嵌套元素。

自Spring Integration 3.0起,它只能在<chain>定义中使用。

原因的根源在这里(GatewayParser):

boolean isNested = parserContext.isNested();
...
gatewayAttributes.put("defaultRequestChannel", element.getAttribute(isNested ? "request-channel" : "default-request-channel"));

对于任何其他情况,您必须将<gateway>配置为根组件,并使用其id注入其他bean。

这只是一个简单的迁移成本:其他情况可能不那么简单:https://github.com/spring-projects/spring-integration/wiki

从另一方面来说,我发现nested解决方案对于Gateway模式定义所呈现的集成非常有用。

我确定有一天你决定使用来自其他服务的相同网关接口。

在这种情况下不要试图处理框架:它只是一个我们应该遵循的API,因为我们必须提供具体类型的对象作为某些Java核心的现有方法的参数类。