重写的RabbitSourceConfiguration(应用程序启动程序)不适用于Spring Cloud Edgware

时间:2017-12-06 11:37:20

标签: spring-cloud spring-cloud-stream spring-cloud-dataflow

我正在测试我的Spring Cloud DataFlow服务从Spring Cloud Dalston.SR4 / Spring Boot 1.5.9升级到Spring Cloud Edgware / Spring Boot 1.5.9。我的一些服务从应用程序启动器扩展源(或接收器)组件。我发现这不适用于Spring Cloud Edgware。

例如,我已覆盖org.springframework.cloud.stream.app.rabbit.source.RabbitSourceConfiguration并将我的应用绑定到我的重写版本。以前,Spring Cloud版本可以使用近一年。

使用Edgware,我得到以下内容(无论应用程序是独立运行还是在数据流中运行):

***************************
APPLICATION FAILED TO START
***************************

Description:

Field channels in org.springframework.cloud.stream.app.rabbit.source.RabbitSourceConfiguration required a bean of type 'org.springframework.cloud.stream.messaging.Source' that could not be found.


Action:

Consider defining a bean of type 'org.springframework.cloud.stream.messaging.Source' in your configuration.

我对spring-cloud-starter-stream-rabbit的1.3.0.RELEASE和1.2.0.RELEASE采取了相同的行为。

我覆盖了RabbitSourceConfiguration,因此我可以在AmqpInboundChannelAdapter上设置标头映射器,并在启动容器之前执行连接测试。

我的子类与@EnableBinding(HeaderMapperRabbitSourceConfiguration.class)绑定到Spring Boot应用程序。我的子类的缩减版本是:

public class HeaderMapperRabbitSourceConfiguration extends RabbitSourceConfiguration {

    public HeaderMapperRabbitSourceConfiguration(final MyHealthCheck healthCheck,
                                                 final MyAppConfig config) {
        // ...
    }

    @Bean
    @Override
    public AmqpInboundChannelAdapter adapter() {
        final AmqpInboundChannelAdapter adapter = super.adapter();
        adapter.setHeaderMapper(new NotificationHeaderMapper(config));

        return adapter;
    }

    @Bean
    @Override
    public SimpleMessageListenerContainer container() {
        if (config.performConnectivityCheckOnStartup()) {

            if (LOGGER.isInfoEnabled()) {
                LOGGER.info("Attempting connectivity with ...");
            }
            final Health health = healthCheck.health();
            if (health.getStatus() == Status.DOWN) {
                LOGGER.error("Unable to connect .....");
                throw new UnableToLoginException("Unable to connect ...");
            } else if (LOGGER.isInfoEnabled()) {
                LOGGER.info("Connectivity established with ...");
            }
        }

        return super.container();
    }
}

1 个答案:

答案 0 :(得分:0)

你真的不应该在healthCheck.health();定义中做@Bean之类的事情。应用程序上下文尚未完全烘焙或启动;它可能会或可能不会起作用,具体取决于创建bean的顺序。

如果您想阻止应用程序启动,请添加一个实现SmartLifecycle的bean,将该bean置于后期(高值),以便在其他所有内容之后启动它。然后将您的代码放入start()autStartup必须是真的。

在这种情况下,它在流基础设施创建频道之前运行。

某些排序可能已从早期版本更改,但无论如何,在@Bean定义中执行此类活动是危险的。

你之前碰巧幸运。

修改

我刚注意到你的@EnableBinding错了;它应该是Source.class。我无法看到它是如何工作的 - 这就是为channels类型的Source字段创建bean的原因。

将流和活页夹更新为1.3.0.RELEASE ...

后,这对我来说很好
@Configuration
public class MySource extends RabbitSourceConfiguration {

    @Bean
    @Override
    public AmqpInboundChannelAdapter adapter() {
        AmqpInboundChannelAdapter adapter = super.adapter();
        adapter.setHeaderMapper(new MyMapper());
        return adapter;
    }


}

@SpringBootApplication
@EnableBinding(Source.class)
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

}

如果这不起作用,请编辑问题以显示您的POM。