将 applicationConfig PropertySource 添加到新环境
Add applicationConfig PropertySource to new Environments
我目前正在将现有应用程序迁移到 Spring Boot 1.2(使用 Mule 3;与 Spring 4.2 不兼容)。这个应用程序包含一个库提供的(我无法修改)servlet,它通过读取一些包含 bean 定义的应用程序包含的 XML 文件来创建几个 ClasspathXmlApplicationContext 来执行 Mule bootstrap 过程。
我的问题是这个 XML 文件包含几个占位符,应该根据活动配置文件以不同方式解析(我已经将这些变量存储在 application.yml 文件中,具有不同的配置文件) ,但 applicationConfig PropertySource 在新应用程序上下文创建的 StandardEnvironments 上不可用。
我可以将 YML 文件转换为 .properties 文件,并在每个 XML 文件中创建一个新的 PropertyPlaceholderConfigurer,指向相同的应用程序-#{systemProperties['spring.profiles.active']}。属性,但是:
我会失去 Boot 使用约定和优先级将 .properties 文件定位在不同 internal/external 位置的灵活性,这对于要通过在不同环境中迁移的应用程序来说听起来很方便。
如果我需要多次添加相同的定义,我想我忽略了一种编程方式。
有人知道如何将 applicationConfig PropertySource 的内容添加到所有新创建的 ApplicationContext 中,而无需修改创建它们的 class 吗? Spring Boot 1.2 没有 EnvironmentPostProcessor 的强大之处。
供将来参考:我已经通过实现一个 ApplicationListener 解决了这个问题,该 ApplicationListener 在所有 PropertySources 中搜索 applicationConfig 的一个并将其所有属性放在 System.getProperties() 地图上,而不是所有人都可以解析的地方通过在 XML 文件上设置一个空的 ApplicationContexts。
当您创建一个新的上下文时,可以使用类似的方法将主环境中的所有 属性 源添加到新创建的上下文中。
public AnnotationConfigApplicationContext createNewApplicationContext(ConfigurableEnvironment mainEnv) throws IOException {
AnnotationConfigApplicationContext newContext = new AnnotationConfigApplicationContext();
//Add scan for your packages
newContext.scan("com.abc.mycompany");
//Also Any different profile in association with new context can be added newContext.getEnvironment().addActiveProfile("newProfile");
mainEnv.getPropertySources().stream().filter(propertySource -> propertySource.getName().startsWith("applicationConfig")).forEach(newContext.getEnvironment().getPropertySources()::addLast);
newContext.refresh();
return newContext;
}
现在您可以根据需要创建任意数量的上下文。另外,为了在所有 bean 创建结束时处理这个问题,您可以 @PostConstruct 并编写一个包装器方法来调用这个新的上下文生成函数。
我目前正在将现有应用程序迁移到 Spring Boot 1.2(使用 Mule 3;与 Spring 4.2 不兼容)。这个应用程序包含一个库提供的(我无法修改)servlet,它通过读取一些包含 bean 定义的应用程序包含的 XML 文件来创建几个 ClasspathXmlApplicationContext 来执行 Mule bootstrap 过程。
我的问题是这个 XML 文件包含几个占位符,应该根据活动配置文件以不同方式解析(我已经将这些变量存储在 application.yml 文件中,具有不同的配置文件) ,但 applicationConfig PropertySource 在新应用程序上下文创建的 StandardEnvironments 上不可用。
我可以将 YML 文件转换为 .properties 文件,并在每个 XML 文件中创建一个新的 PropertyPlaceholderConfigurer,指向相同的应用程序-#{systemProperties['spring.profiles.active']}。属性,但是:
我会失去 Boot 使用约定和优先级将 .properties 文件定位在不同 internal/external 位置的灵活性,这对于要通过在不同环境中迁移的应用程序来说听起来很方便。
如果我需要多次添加相同的定义,我想我忽略了一种编程方式。
有人知道如何将 applicationConfig PropertySource 的内容添加到所有新创建的 ApplicationContext 中,而无需修改创建它们的 class 吗? Spring Boot 1.2 没有 EnvironmentPostProcessor 的强大之处。
供将来参考:我已经通过实现一个 ApplicationListener 解决了这个问题,该 ApplicationListener 在所有 PropertySources 中搜索 applicationConfig 的一个并将其所有属性放在 System.getProperties() 地图上,而不是所有人都可以解析的地方通过在 XML 文件上设置一个空的 ApplicationContexts。
当您创建一个新的上下文时,可以使用类似的方法将主环境中的所有 属性 源添加到新创建的上下文中。
public AnnotationConfigApplicationContext createNewApplicationContext(ConfigurableEnvironment mainEnv) throws IOException {
AnnotationConfigApplicationContext newContext = new AnnotationConfigApplicationContext();
//Add scan for your packages
newContext.scan("com.abc.mycompany");
//Also Any different profile in association with new context can be added newContext.getEnvironment().addActiveProfile("newProfile");
mainEnv.getPropertySources().stream().filter(propertySource -> propertySource.getName().startsWith("applicationConfig")).forEach(newContext.getEnvironment().getPropertySources()::addLast);
newContext.refresh();
return newContext;
}
现在您可以根据需要创建任意数量的上下文。另外,为了在所有 bean 创建结束时处理这个问题,您可以 @PostConstruct 并编写一个包装器方法来调用这个新的上下文生成函数。