CamelContextStartedEvent调用了两次

时间:2018-07-06 13:29:46

标签: spring spring-boot apache-camel spring-camel

对于同一骆驼上下文(骆驼1),CamelContextStartedEvent被两次调用。问题可能是我注册EventNotifier的方式。您可以使用Spring Boot 1.5.14,Spring Boot Camel Starter 2.21.1和Spring Boot Web Starter重现Spring Initializr的问题。

查看日志:

2018-07-06 11:04:41.104  INFO 19092 --- [           main] o.a.camel.spring.SpringCamelContext      : Apache Camel 2.21.1 (CamelContext: camel-1) is starting
2018-07-06 11:04:41.106  INFO 19092 --- [           main] o.a.c.m.ManagedManagementStrategy        : JMX is enabled
2018-07-06 11:04:41.191  INFO 19092 --- [           main] o.a.camel.spring.SpringCamelContext      : StreamCaching is not in use. If using streams then its recommended to enable stream caching. See more details at http://camel.apache.org/stream-caching.html
2018-07-06 11:04:41.193  INFO 19092 --- [           main] o.a.camel.spring.boot.RoutesCollector    : Starting CamelMainRunController to ensure the main thread keeps running
2018-07-06 11:04:41.193  INFO 19092 --- [           main] o.a.camel.spring.SpringCamelContext      : Total 0 routes, of which 0 are started
2018-07-06 11:04:41.194  INFO 19092 --- [           main] o.a.camel.spring.SpringCamelContext      : Apache Camel 2.21.1 (CamelContext: camel-1) started in 0.090 seconds
2018-07-06 11:04:41.195  INFO 19092 --- [           main] c.e.bug.service.StartupEventNotifier     : CamelContextStartedEvent for SpringCamelContext(camel-1) with spring id application:11223
2018-07-06 11:04:41.195  INFO 19092 --- [           main] c.e.bug.service.StartupEventNotifier     : CamelContextStartedEvent for SpringCamelContext(camel-1) with spring id application:11223
2018-07-06 11:04:41.216  INFO 19092 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 11223 (http)
2018-07-06 11:04:41.221  INFO 19092 --- [           main] com.example.bug.BugApplication           : Started BugApplication in 4.684 seconds (JVM running for 6.773)

用于初始化EventNotifier的服务:

@Service
public class SchedulerService {

    private final CamelContext camelContext;

    private final StartupEventNotifier startupEventNotifier;

    public SchedulerService(CamelContext camelContext, StartupEventNotifier startupEventNotifier) {
        this.camelContext = camelContext;
        this.startupEventNotifier = startupEventNotifier;
    }

    @PostConstruct
    public void init() {
        camelContext.getManagementStrategy().addEventNotifier(startupEventNotifier);
    }

}

EventNotifier

@Component
public class StartupEventNotifier extends EventNotifierSupport {

    private static final Logger logger = LoggerFactory.getLogger(StartupEventNotifier.class);

    @Override
    public void notify(EventObject event) throws Exception {
        if (event instanceof CamelContextStartedEvent) {
            logger.info("CamelContextStartedEvent for {}", event.getSource());
        }
    }

    @Override
    public boolean isEnabled(EventObject event) {
        if (event instanceof CamelContextStartedEvent) {
            return true;
        }
        return false;
    }
}

application.yml:

camel:
  springboot:
    main-run-controller: true
server:
  port: 11223

1 个答案:

答案 0 :(得分:3)

它被两次调用,因为它被两次注册。一次由您,一次由Apache Camel。如果EventNotifier中有Registry,则会自动注册。由于您的StartupEventNotifier被注释为Component,因此它是Registry的一部分,并且Apache Camel在CamelContext启动期间对其进行了注册(您可以在{{3}中看到它}第424行)

您有四个选择:

  • SchedulerService删除自定义注册。
  • @Component删除StartupEventNotifier批注,并向camelContext.getManagementStrategy().addEventNotifier(new StartupEventNotifier())注册
  • 向您的SchedulerService添加重复性检查。像这样:

    if (!context.getManagementStrategy().getEventNotifiers().contains(startupEventNotifier)){
        context.getManagementStrategy().addEventNotifier(startupEventNotifier);
    }
    
  • EventNotifier的{​​{1}}中注册@PostConstruct。它会在开始自动发现之前被注册,然后在CamelAutoConfiguration (请参见第422行)

  • 中被跳过