Spring Integration升级5.5.18时default-output-channel缺失Bean报错
这是Spring Integration 5.2及后续版本(你升级到的5.5.x属于此范围)对通道自动创建逻辑调整导致的差异:
5.1.x版本的行为
在5.1.x中,只要配置(XML或注解)里引用了未显式定义的通道名称,框架会自动创建对应的DirectChannel Bean——不管这个通道是被顶级组件引用,还是像你这样在chain内部的header-value-router的default-output-channel中使用,都会触发自动创建。
5.2+版本的行为
从5.2开始,通道自动创建的逻辑做了限制:
- 仅当通道被顶级组件(比如根上下文的
@ServiceActivator、@Gateway等注解)引用时,才会自动生成通道Bean。 - 对于嵌套组件(比如
chain内部的路由器、过滤器等)中引用的通道,框架不再自动创建对应的Bean。因为chain属于嵌套集成组件,其内部的通道引用解析时机更早,此时注解触发的通道自动创建还未完成,导致XML中的路由器初始化时找不到目标通道Bean,从而抛出找不到Bean的错误。
你的场景里,unsupportedOutGatewayChannel是在chain内部的路由器中作为默认输出通道引用的,属于嵌套组件的引用,因此新版本不会自动创建这个通道;而@ServiceActivator注解的通道引用触发的自动创建,发生在XML配置的Bean初始化之后,无法提前满足路由器的依赖。
你提到可以手动定义Bean,这里给出两种可行方案:
方案1:显式定义通道Bean
这是最稳定的方式,在配置类或XML中直接定义通道:
@Bean public MessageChannel unsupportedOutGatewayChannel() { return new DirectChannel(); }
或者用XML配置:
<int:channel id="unsupportedOutGatewayChannel"/>
方案2:延迟通道解析(可选)
如果不想手动定义,可以通过SpEL延迟通道的查找时机,直到第一次发送消息时(此时注解触发的自动创建已完成):
修改XML中路由器的default-output-channel属性为:
default-output-channel="#{@unsupportedOutGatewayChannel}"
不过这种方式稳定性不如显式定义,建议优先选方案1。
如果你计划最终升级到Spring Boot 3.x(对应Spring Integration 6.x),需要注意:通道自动创建的默认行为会被完全禁用,所有通道都必须显式定义,提前适应显式定义的方式会让后续升级更顺畅。
内容的提问来源于stack exchange,提问作者Yury K.

