CamelContextStartedEvent 调用了两次
CamelContextStartedEvent called twice
对于同一个 camel 上下文 (camel-1),CamelContextStartedEvent
被调用了两次。问题可能是我注册 EventNotifier
的方式。您可以使用 Spring Initializr 和 Spring Boot 1.5.14、Spring Boot Camel Starter 2.21.1 和 Spring Boot Web Starter 重现该问题。
查看日志:
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
调用了两次,因为注册了两次。一次是你,一次是 Apache Camel。如果在 Registry
中找到 EventNotifier
,则会自动注册。由于您的 StartupEventNotifier
被注释为 Component
,它是 Registry
的一部分并且 Apache Camel 在 CamelContext
启动期间注册了它 (您可以在 CamelAutoConfiguration
第 424 行).
你有四种选择:
- 从
SchedulerService
中删除您的自定义注册。
- 从
StartupEventNotifier
中删除 @Component
注释并使用 camelContext.getManagementStrategy().addEventNotifier(new StartupEventNotifier())
注册
为您的 SchedulerService
添加口是心非检查。类似于:
if (!context.getManagementStrategy().getEventNotifiers().contains(startupEventNotifier)){
context.getManagementStrategy().addEventNotifier(startupEventNotifier);
}
在 RouteBuilder
的 @PostConstruct
中注册 EventNotifier
。它会在自动发现开始之前注册,然后在CamelAutoConfiguration
(见第422行)
中跳过
对于同一个 camel 上下文 (camel-1),CamelContextStartedEvent
被调用了两次。问题可能是我注册 EventNotifier
的方式。您可以使用 Spring Initializr 和 Spring Boot 1.5.14、Spring Boot Camel Starter 2.21.1 和 Spring Boot Web Starter 重现该问题。
查看日志:
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
调用了两次,因为注册了两次。一次是你,一次是 Apache Camel。如果在 Registry
中找到 EventNotifier
,则会自动注册。由于您的 StartupEventNotifier
被注释为 Component
,它是 Registry
的一部分并且 Apache Camel 在 CamelContext
启动期间注册了它 (您可以在 CamelAutoConfiguration
第 424 行).
你有四种选择:
- 从
SchedulerService
中删除您的自定义注册。 - 从
StartupEventNotifier
中删除@Component
注释并使用camelContext.getManagementStrategy().addEventNotifier(new StartupEventNotifier())
注册
为您的
SchedulerService
添加口是心非检查。类似于:if (!context.getManagementStrategy().getEventNotifiers().contains(startupEventNotifier)){ context.getManagementStrategy().addEventNotifier(startupEventNotifier); }
在
RouteBuilder
的@PostConstruct
中注册EventNotifier
。它会在自动发现开始之前注册,然后在CamelAutoConfiguration
(见第422行) 中跳过