首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >由Spring上下文加载两次ApplicationContextInitializer & Spring

由Spring上下文加载两次ApplicationContextInitializer & Spring
EN

Stack Overflow用户
提问于 2019-01-02 12:46:22
回答 1查看 1.3K关注 0票数 2

当在spring.factories文件中声明初始化器以创建starters时,我们意识到这些初始化器被加载了两次:

  • 一次通过上下文
  • 一次通过Spring上下文

在我们的例子中,我们在docker容器中启动数据库,所以我们不想做两次。

根据这个问题,这是Spring的预期行为:https://github.com/spring-cloud/spring-cloud-config/issues/1151

当询问引导上下文应该如何与“常规”应用程序上下文区分时,给出的答案是

检查上下文的ID。

运行示例应用程序后,ConfigurableApplicationContext.getId()默认返回:

  • Spring上下文的application
  • 用于Spring上下文的application-1

我们的一些用户没有定义spring.application.name,还有一些用户根本不使用Spring。

问题:我们如何才能可靠地加载一个初始化器一次?

如果ApplicationContextInitializer的含义是幂等的,那么它可能会出现在接口的Javadocs中。

在最坏的情况下,我们如何安全地区分Spring引导上下文和Spring上下文?

EN

回答 1

Stack Overflow用户

发布于 2019-01-04 21:11:25

在试图向EnvironmentPostProcessor 这里中注入属性源时,我们遇到了同样的问题。解决方案非常简单,因为您只需要一个静态标志:

代码语言:javascript
复制
public class YourInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext>
{
    private static boolean initialized = false;

    @Override
    public void initialize(ConfigurableApplicationContext applicationContext)
    {
        if (!initialized) {
            //do your things here
            initialized = true;
        }
    }
}

引导应用程序上下文总是在常规Spring应用程序上下文之前运行,因此您也可以使用它在正确的位置运行代码。

最后,在BootstrapApplicationListener中实例化引导上下文。从这里,您可以看到spring.application.name属性被设置为spring.cloud.bootstrap.namebootstrap的值作为后盾。然后将其设置为ContextIdApplicationContextInitializer中应用程序上下文的id。您还可以使用它来确定您的初始化程序在哪个上下文中运行。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54006653

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档