gpt4 book ai didi

java - 监听器未收到 ApplicationPreparedEvent

转载 作者:行者123 更新时间:2023-12-02 12:20:13 30 4
gpt4 key购买 nike

我有一个 Spring Boot 1.5.4 应用程序,它在启动时注册一个日志附加程序,这要归功于监听器,并且它可以与此处解释的解决方案一起使用 register custom log appender in spring boot starter 。监听器是我编写的启动器的一部分,并且我的带有 @EnableAutoConfiguration 的应用程序按预期工作。

我有 2 个其他应用程序使用相同的 Spring Boot 版本,我想为其使用相同的启动器。我相信它们与工作应用程序具有或多或少相同的配置,但 onApplicationEvent 方法永远不会被调用,因此我的日志附加程序未注册。下面是我的配置+监听器类。

我在supportsEventType方法中放置了一个断点,对于传递到那里的所有事件,没有一个像我的第一个应用程序中那样属于ApplicationPreparedEvent类型。

@Configuration
@EnableConfigurationProperties(MetricProperties.class)
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class MetricsAutoConfiguration implements GenericApplicationListener {

private final MetricProperties metricProperties;
private boolean addedCustomAppender = false;

public MetricsAutoConfiguration(MetricProperties metricProperties) {
this.metricProperties = metricProperties;
}


@Bean
@ConditionalOnProperty(name = "metrics.enabled", havingValue = "true")
public EventsPublisher metricPublisher() {
metricProperties.validate();
return new EventsPublisher(metricProperties);
}



@Override

public void onApplicationEvent(ApplicationEvent event) {
if (metricProperties.isEnabled() && !addedCustomAppender) {

ApplicationPreparedEvent applicationEvent = (ApplicationPreparedEvent) event;
EventsPublisher eventPublisher = applicationEvent.getApplicationContext().getBean(EventsPublisher.class);

//register the log appender
// removed for brevity

addedCustomAppender = true;
}
}


@Override
public int getOrder() {
// this must be higher than LoggingApplicationListener.DEFAULT_ORDER
return Ordered.HIGHEST_PRECEDENCE + 21;
}

@Override
public boolean supportsEventType(ResolvableType eventType) {

return ApplicationPreparedEvent.class.isAssignableFrom(eventType.getRawClass());
}

@Override
public boolean supportsSourceType(Class<?> sourceType) {
return true;
}

}

在它工作的应用程序中,我看到构建了 3 个 ApplicationPreparedEvent,并且supportsEventsType 返回 true 两次(并且 onApplicationEvent 被调用两次,使用相同的事件):这发生在第 3 个 ApplicationPreparedEvent 构建之后,而不是之前。

应用程序注释是:

@SpringBootApplication
@EnableZuulProxy
@EnableBinding(OutPutChannel.class)
@EnableAutoConfiguration(exclude = MetricsDropwizardAutoConfiguration.class)
@IntegrationComponentScan

对于它不起作用的其他应用程序,我观察到在启动时仅构建了 1 个 ApplicationPreparedEvent 并且它不会触发监听器,因为调用了supportsEventsType但从未返回 true :

  • 对于第一个应用程序,它依次被调用:

    • org.springframework.boot.builder.ParentContextApplicationContextInitializer$ParentContextAvailableEvent(两次)
    • org.springframework.context.event.ContextRefreshedEvent(两次)
    • org.springframework.boot.context.event.ApplicationReadyEvent(两次)

应用程序注释是:

@SpringBootApplication
@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class,
DataSourceTransactionManagerAutoConfiguration.class,
HibernateJpaAutoConfiguration.class,
MetricsDropwizardAutoConfiguration.class,
JestAutoConfiguration.class})
  • 对于第二个应用程序:
    • org.springframework.context.event.ContextRefreshedEvent(两次)
    • org.springframework.boot.context.embedded.EmbeddedServletContainerInitializedEvent(两次)
    • org.springframework.boot.context.event.ApplicationReadyEvent(两次)

带有注释:

@SpringBootApplication
@EnableAutoConfiguration(exclude = JestAutoConfiguration.class)

对于这两种情况,都没有监听器“测试”ApplicationPreparedEvent 的痕迹...

有什么提示吗?我很困惑……

谢谢

最佳答案

在逐一删除/添加依赖项并每次进行比较后,我发现了它起作用(或不起作用)的原因,尽管我还不明白为什么......

为了让我的应用程序正确注册监听器,我需要依赖于

    <dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>

这没有多大意义,但是其中有一些东西很早就生成了 ApplicationPreparedEvent, Spring 横幅显示在日志中。在横幅显示和日​​志行显示

后构建第二个事件
The following profiles are active: XXXX

通过该配置,我可以看到我的监听器接收第二个事件并进行配置。

如果我删除对 spring-cloud-starter-feign 的依赖,则在横幅显示后(之前什么也没有),只会构建一个 ApplicationPreparedEvent,并且我的监听器永远不会收到它。

<小时/>

深入挖掘依赖关系树后,我将其范围缩小到 spring-cloud-context (我使用 1.2.2.RELEASE)。那里有一些东西会触发很早的 ApplicationPreparedEvent ,使我的监听器能够注册。我什至排除了它必须确定的唯一依赖项:

    <dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-context</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-crypto</artifactId>
</exclusion>
</exclusions>
</dependency>

如果有人有更多这方面的信息或更好的方法来实现这一点,请随时发表评论

关于java - 监听器未收到 ApplicationPreparedEvent,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45845970/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com