在初始化 Spring Boot 应用程序之前寻找一种在 spring boot application.yml 文件中解析值的方法

Looking for a way to parse values in springboot application.yml file before SpringBootApplication is initialized

所以我的问题如下:

我正在使用 spring AMQP 连接到使用 SSL 的 rabbitMQ 实例。不幸的是,spring AMQP 当前不支持全长 amqps URI,添加支持的优先级不高(参见问题:https://github.com/spring-projects/spring-boot/issues/6401)。他们需要分开。

我的 application.yml 中需要以下字段才能连接:

spring:
  rabbitmq:
    host: hostname
    port: portnumber
    username: username
    password: password
    virtual-host: virtualhost
    ssl:
      enabled: true

我的 rabbitMQ 实例的 VCAP_Services 环境仅提供以下格式的虚拟主机和全长 uri:amqps://username:password@hostname:portnumber/virtualhost

将这些值复制并粘贴到我的 application.yml 中目前没问题,但从长远来看 运行 是不可行的。他们需要来自 vcap_services.

我的@SpringBootApplication 具有在启动时初始化与 rabbitMQ 实例的连接的 @Beans,因此我正在寻找一种方法来解析各个值并在应用程序启动之前设置它们。

只需覆盖 Boot 的自动配置连接工厂...

@SpringBootApplication
public class So46937522Application {

    public static void main(String[] args) {
        SpringApplication.run(So46937522Application.class, args);
    }

    @Bean
    public CachingConnectionFactory rabbitConnectionFactory(RabbitProperties config)
            throws Exception {
        CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
        connectionFactory.getRabbitConnectionFactory()
            .setUri("amqps://guest:guest@10.0.0.3:5671/virtualhost");
        return connectionFactory;
    }

    @RabbitListener(queues = "si.test.queue")
    public void listen(Message in) {
        System.out.println(in);
    }

}

如果您只是想在 Spring 启动应用程序初始化之前阅读属性,您可以在调用 [=] 之前使用 Spring 的 YamlPropertiesFactoryBean 解析 yaml 文件12=]。例如,

@SpringBootApplication
public class Application {

    public static void main(String[] args) {       
        YamlPropertiesFactoryBean yamlFactory = new YamlPropertiesFactoryBean();
        yamlFactory.setResources(new ClassPathResource("application.yml"));
        Properties props = yamlFactory.getObject();

        String hostname = props.getProperty("spring.rabbitmq.hostname");
        ...

        SpringApplication.run(Application.class, args);
    }
}