我正在测试我的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();
}
}
答案 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。