Spring boot Spring云引导上下文加载两次ApplicationContextInitializer&;弹簧靴
在Spring boot Spring云引导上下文加载两次ApplicationContextInitializer&;弹簧靴,spring-boot,spring-cloud,Spring Boot,Spring Cloud,在spring.factories文件中声明初始值设定项以创建spring启动启动器时,我们意识到这些初始值设定项加载了两次: 一次由Spring Cloud Boostrap上下文执行 一次通过Spring引导上下文 在我们的例子中,我们在docker容器中启动数据库,所以我们不想重复两次 根据这个问题,这是Spring Cloud的预期行为: 当问及boostrap上下文应该如何区别于“常规”应用程序上下文时,给出的答案是 检查上下文的ID 运行示例应用程序后,ConfigurableA
spring.factories
文件中声明初始值设定项以创建spring启动启动器时,我们意识到这些初始值设定项加载了两次:
- 一次由Spring Cloud Boostrap上下文执行
- 一次通过Spring引导上下文
ConfigurableApplicationContext.getId()
默认返回:
用于Spring云引导上下文应用程序
用于Spring引导上下文application-1
spring.application.name
,其他用户根本不使用spring云
问题:我们如何才能可靠地只加载一次初始值设定项
如果ApplicationContextInitializer
s是幂等的,那么它可能会出现在接口的Javadocs中
在最坏的情况下,我们如何安全地将Spring Cloud boostrap上下文与Spring启动上下文区分开来?我们在尝试将属性源注入
环境后处理器时遇到了相同的问题。解决方案非常简单,因为您只需要一个静态标志:
public类初始值设定项实现ApplicationContextInitializer
{
私有静态布尔初始化=false;
@凌驾
public void初始化(ConfigurableApplicationContext applicationContext)
{
如果(!已初始化){
//在这里做你的事情
初始化=真;
}
}
}
引导应用程序上下文将始终在常规Spring引导应用程序上下文之前运行,因此您也可以使用它在正确的位置运行代码
最后,在bootstrapplicationlistener
中实例化引导上下文。从那里,您可以看到spring.application.name
属性被设置为spring.cloud.bootstrap.name
或bootstrap
的值,作为一种后备方法。然后将其设置为ContextIdApplicationContextInitializer
中应用程序上下文的id。您还可以使用它来确定初始值设定项在哪个上下文中运行