如何创建依赖于 Spring Bean 的自定义 Spring PropertySource

Posted

技术标签:

【中文标题】如何创建依赖于 Spring Bean 的自定义 Spring PropertySource【英文标题】:How to create a custom Spring PropertySource that depends on a Spring Bean 【发布时间】:2015-05-16 05:54:54 【问题描述】:

我正在尝试将 spring-cloud 堆栈用于将使用 Zuul 的项目。在我的组织中,我们有一个基于 xml 的自定义配置堆栈,并进行属性组合和分层覆盖。由于处理此配置的方式,我一直在努力为其创建 PropertySource。

我的自定义 PropertySource 必须使用我的 Config bean,但是因为 PropertySources 在 Spring Boot 的引导过程中被初始化,所以应用程序上下文还没有完全初始化,我无法访问我的自定义 Bean,它公开了我们基于 xml 的配置系统。

@ConfigurationProperties 似乎完全偏向于 .properties 和 .yaml 文件。 Config bean 在 ApplicationContextInitializer 中初始化。有没有办法在各种服务中延迟 ConfigurationProperties 的解析,以便在初始化后使用我的 Config bean 构造我的自定义属性源?

【问题讨论】:

[spring-cloud-consul-config][1] 使用spring cloud config引导机制,让正常的应用上下文有值。 [1]:github.com/spring-cloud/spring-cloud-consul/tree/master/… 谢谢斯宾塞。这是一个有用的链接,它具体演示了 Syer 先生链接的官方文档中提到的内容。 【参考方案1】:

我最初尝试(在提出问题之前)在我的配置中创建一个自定义 PropertySourceLocator(如 Dave Syer 所述,并在他提供的链接中有详细记录)并将其注册到我自己的 spring.factories (再次,在Spencer Gibb 在评论中给出的有用链接。)问题是我的属性源需要在 ApplicationContextInitializer 中完成一些工作之后进行配置,并且属性源似乎在此之前都已解决(至少那些连线的)作为 org.springframework.cloud.bootstrap.BootstrapConfiguration 的工厂)。我想我暗示我在我的 PropertySource 中需要一个特定的 bean,而当时我无法从 ApplicationContext 中获得它。

无论如何,为了解决这个问题,我现在在 PriorityOrdered ApplicationContextInitializer 中注册属性源,以便在另一个初始化我的配置对象之后发生。比如:context.getEnvironment().getPropertySources().addFirst(myPropertySource);

这似乎让我的属性源在正确的时间进入环境,并允许我根据需要事先对上下文进行自定义。

【讨论】:

PriorityOrdered 是什么意思?这是某种确保它首先运行的注释吗?否则,如何让它先运行?谢谢【参考方案2】:

在 Spring Cloud 中,您需要注册一些具有 PropertySourceLocator bean 的 BootstrapConfiguration(根据用户指南:http://projects.spring.io/spring-cloud/spring-cloud.html#customizing-bootstrap-property-sources)。应该不会比这更难。

附: @ConfigurationProperties 不偏向于 .properties 和 .yaml 文件 - 它绑定到对文件格式一无所知的 Environment

【讨论】:

对 ConfigurationProperties 采取的观点不偏向 .properties 和 .yaml 文件。似乎在配置中,任何类型的覆盖都应该以这种方式完成。我遇到麻烦的地方是我正在实现 PropertySource 而不是 EnumerablePropertySource (通过 Spencer 的链接找到),因此无法正确映射我的自定义属性。遗憾的是,我没有找到任何关于应该从 PropertySource 中的 getProperty 返回的内容的优秀文档,并且 Object 并不是很直观。是的,我知道我只是听起来很困惑......

以上是关于如何创建依赖于 Spring Bean 的自定义 Spring PropertySource的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot:来自库项目的自动装配 bean

如何创建不依赖于 ASP.NET Core 声明的自定义 Authorize 属性?

Spring:bean的循环依赖问题

spring如何开启允许循环依赖

Spring IoCSpring Bean

Spring核心技术——Spring中Bean的作用域