Spring boot 为什么Spring启动应用程序记录在添加Spring云总线依赖项后启动了两次
这是我的Spring boot应用程序中的简单代码:Spring boot 为什么Spring启动应用程序记录在添加Spring云总线依赖项后启动了两次,spring-boot,rabbitmq,spring-amqp,spring-rabbit,spring-cloud-bus,Spring Boot,Rabbitmq,Spring Amqp,Spring Rabbit,Spring Cloud Bus,这是我的Spring boot应用程序中的简单代码: package com.maxxton.SpringBootHelloWorld; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class SpringBootHelloWorldApp
package com.maxxton.SpringBootHelloWorld;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringBootHelloWorldApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootHelloWorldApplication.class, args);
}
}
以及用于侦听ApplicationEvent的ApplicationListener类:
package com.maxxton.SpringBootHelloWorld;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
@Component
public class Test implements ApplicationListener {
@Override
public void onApplicationEvent(ApplicationEvent event) {
if (event.getClass().getSimpleName().equals("ApplicationReadyEvent")) {
System.out.println("-------------------------------------");
System.out.println(event.getClass().getSimpleName());
System.out.println("-------------------------------------");
}
}
}
build.gradle包含以下依赖项:
dependencies {
compile("org.springframework.boot:spring-boot-starter-amqp")
compile("org.springframework.cloud:spring-cloud-starter-bus-amqp")
compile('org.springframework.boot:spring-boot-starter-web')
compile('org.springframework.boot:spring-boot-starter')
compile("org.springframework.cloud:spring-cloud-starter")
compile("org.springframework.cloud:spring-cloud-starter-security")
compile("org.springframework.cloud:spring-cloud-starter-eureka")
testCompile('org.springframework.boot:spring-boot-starter-test')
}
compile("org.springframework.boot:spring-boot-starter-amqp")
compile("org.springframework.cloud:spring-cloud-starter-bus-amqp")
现在,当我运行这个spring boot应用程序时,我看到这个日志打印了两次:
[main] c.m.S.SpringBootHelloWorldApplication : Started SpringBootHelloWorldApplication in ... seconds (JVM running for ...)
通常,此日志只打印一次,但如果添加以下依赖项,则会打印两次:
dependencies {
compile("org.springframework.boot:spring-boot-starter-amqp")
compile("org.springframework.cloud:spring-cloud-starter-bus-amqp")
compile('org.springframework.boot:spring-boot-starter-web')
compile('org.springframework.boot:spring-boot-starter')
compile("org.springframework.cloud:spring-cloud-starter")
compile("org.springframework.cloud:spring-cloud-starter-security")
compile("org.springframework.cloud:spring-cloud-starter-eureka")
testCompile('org.springframework.boot:spring-boot-starter-test')
}
compile("org.springframework.boot:spring-boot-starter-amqp")
compile("org.springframework.cloud:spring-cloud-starter-bus-amqp")
这是完整的日志:
2017-11-17 15:44:07.372 INFO 5976 --- [ main] o.s.c.support.GenericApplicationContext : Refreshing org.springframework.context.support.GenericApplicationContext@31c7c281: startup date [Fri Nov 17 15:44:07 IST 2017]; root of context hierarchy
-------------------------------------
ApplicationReadyEvent
-------------------------------------
2017-11-17 15:44:07.403 INFO 5976 --- [ main] c.m.S.SpringBootHelloWorldApplication : Started SpringBootHelloWorldApplication in 1.19 seconds (JVM running for 10.231)
2017-11-17 15:44:09.483 WARN 5976 --- [ main] o.s.amqp.rabbit.core.RabbitAdmin : Failed to declare exchange: Exchange [name=springCloudBus, type=topic, durable=true, autoDelete=false, internal=false, arguments={}], continuing... org.springframework.amqp.AmqpConnectException: java.net.ConnectException: Connection refused: connect
2017-11-17 15:44:09.492 INFO 5976 --- [ main] o.s.integration.channel.DirectChannel : Channel 'a-bootiful-client.springCloudBusOutput' has 1 subscriber(s).
2017-11-17 15:44:09.493 INFO 5976 --- [ main] o.s.c.support.DefaultLifecycleProcessor : Starting beans in phase 0
2017-11-17 15:44:09.530 INFO 5976 --- [ main] o.s.i.endpoint.EventDrivenConsumer : Adding {logging-channel-adapter:_org.springframework.integration.errorLogger} as a subscriber to the 'errorChannel' channel
2017-11-17 15:44:09.530 INFO 5976 --- [ main] o.s.i.channel.PublishSubscribeChannel : Channel 'a-bootiful-client.errorChannel' has 1 subscriber(s).
2017-11-17 15:44:09.530 INFO 5976 --- [ main] o.s.i.endpoint.EventDrivenConsumer : started _org.springframework.integration.errorLogger
2017-11-17 15:44:09.530 INFO 5976 --- [ main] o.s.c.support.DefaultLifecycleProcessor : Starting beans in phase 2147482647
2017-11-17 15:44:09.539 INFO 5976 --- [ main] c.s.b.r.p.RabbitExchangeQueueProvisioner : declaring queue for inbound: springCloudBus.anonymous.kZ1vvxHaRfChKe1TncH-MQ, bound to: springCloudBus
2017-11-17 15:44:11.562 WARN 5976 --- [ main] o.s.amqp.rabbit.core.RabbitAdmin : Failed to declare exchange: Exchange [name=springCloudBus, type=topic, durable=true, autoDelete=false, internal=false, arguments={}], continuing... org.springframework.amqp.AmqpConnectException: java.net.ConnectException: Connection refused: connect
2017-11-17 15:44:13.587 WARN 5976 --- [ main] o.s.amqp.rabbit.core.RabbitAdmin : Failed to declare queue: Queue [name=springCloudBus.anonymous.kZ1vvxHaRfChKe1TncH-MQ, durable=false, autoDelete=true, exclusive=true, arguments={}], continuing... org.springframework.amqp.AmqpConnectException: java.net.ConnectException: Connection refused: connect
2017-11-17 15:44:15.611 WARN 5976 --- [ main] o.s.amqp.rabbit.core.RabbitAdmin : Failed to declare binding: Binding [destination=springCloudBus.anonymous.kZ1vvxHaRfChKe1TncH-MQ, exchange=springCloudBus, routingKey=#], continuing... org.springframework.amqp.AmqpConnectException: java.net.ConnectException: Connection refused: connect
2017-11-17 15:44:17.662 INFO 5976 --- [ main] o.s.i.a.i.AmqpInboundChannelAdapter : started inbound.springCloudBus.anonymous.kZ1vvxHaRfChKe1TncH-MQ
2017-11-17 15:44:17.662 INFO 5976 --- [ main] o.s.i.endpoint.EventDrivenConsumer : Adding {message-handler:inbound.springCloudBus.default} as a subscriber to the 'bridge.springCloudBus' channel
2017-11-17 15:44:17.662 INFO 5976 --- [ main] o.s.i.endpoint.EventDrivenConsumer : started inbound.springCloudBus.default
2017-11-17 15:44:17.663 INFO 5976 --- [ main] o.s.c.support.DefaultLifecycleProcessor : Starting beans in phase 2147483647
2017-11-17 15:44:17.714 INFO 5976 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http)
-------------------------------------
ApplicationReadyEvent
-------------------------------------
2017-11-17 15:44:17.717 INFO 5976 --- [ main] c.m.S.SpringBootHelloWorldApplication : Started SpringBootHelloWorldApplication in 20.131 seconds (JVM running for 20.545)
如您所见,ApplicationReadyEvent发生了两次
为什么会这样?
有什么方法可以避免这种情况吗?您的应用程序.yml/.xml中是否使用多绑定rabbitmq配置 如果是肯定的,那么您可以尝试排除RabbitAutoConfiguration
@EnableDiscoveryClient
@EnableAutoConfiguration(exclude = {RabbitAutoConfiguration.class})
@SpringBootApplication
public class SpringBootHelloWorldApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootHelloWorldApplication.class, args);
}
}
SpringCloudBus使用SpringCloudStream,它将绑定器放在单独的启动子应用程序上下文中 您应该让事件侦听器知道它正在运行的应用程序上下文。您还可以使用泛型来选择您感兴趣的事件类型
@Component
public class Test implements ApplicationListener<ApplicationReadyEvent>,
ApplicationContextAware {
private ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
@Override
public void onApplicationEvent(ApplicationReadyEvent event) {
if (event.getApplicationContext().equals(this.applicationContext)) {
System.out.println("-------------------------------------");
System.out.println(event.getClass().getSimpleName());
System.out.println("-------------------------------------");
}
}
}
@组件
公共类测试实现ApplicationListener,
ApplicationContextAware{
私有应用程序上下文应用程序上下文;
@凌驾
public void setApplicationContext(ApplicationContext ApplicationContext)抛出BeansException{
this.applicationContext=applicationContext;
}
@凌驾
ApplicationEvent上的公共无效(ApplicationReadyEvent事件){
if(event.getApplicationContext().equals(this.applicationContext)){
System.out.println(“-----------------------------------------”;
System.out.println(event.getClass().getSimpleName());
System.out.println(“-----------------------------------------”;
}
}
}
不,我没有使用多个绑定。从未使用过Spring Cloud Bus,但看起来可能是它导致了这种情况。根据,您可以启用跟踪,以便查看并检查是否存在错误。一个疯狂的想法可能是,应用程序正在侦听自己的状态更改,因此消耗自己的事件并复制输出…因此,您是说,@gary russell如果我们使用spring云总线依赖项,“Started SpringBootHelloWorldApplication in…”将被记录两次,因为spring cloud bus使用spring cloud stream,它将绑定器放在一个单独的启动子系统中。只有在您不接受我的建议并让您的侦听器知道它声明为int的应用程序上下文时,才会记录两次。我已根据您的建议进行了更改,现在侦听器感知只打印了一次,但是“已在中启动SpringBootHelloWorldApplication…”仍记录了两次。