【问题标题】:Spring boot configuration with environment variables带有环境变量的 Spring Boot 配置
【发布时间】:2018-07-31 06:27:48
【问题描述】:

我有一个 Spring Boot 应用程序,它与 DB 交互以使用 Spring data Rest 提供资源。我想从环境变量中获取配置。下面是我的属性文件。

spring.datasource.url=${mysql.url}
spring.datasource.username=${mysql.user}
spring.datasource.password=${mysql.password}

我的环境变量在图片https://ibb.co/cyxsNc

我什至也尝试过以下配置

spring.datasource.url=${MySQL_Url}
spring.datasource.username=${MySQL_User}
spring.datasource.password=${MySQL_Password}

但我无法连接到数据库并收到以下错误

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration': Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Tomcat.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.apache.tomcat.jdbc.pool.DataSource]: Factory method 'dataSource' threw exception; nested exception is java.lang.IllegalArgumentException: URL must start with 'jdbc'

应用程序文件夹结构

Project
|-- src/main/java
    |-- com.example.app
        |-- DemoApplication.java
|-- src/main/resources
    |-- application.properties

注意:如果我设置如下值,配置工作正常

spring.datasource.url=jdbc:mysql://localhost:3306/ex_man
spring.datasource.username=root
spring.datasource.password=root

我错过了什么?

【问题讨论】:

  • 不要使用屏幕截图,因为主机可能会宕机。最好是代码摘录。
  • @Sp Sesha,请发布您的主要配置类(如果有)和项目结构。很可能您的应用程序上下文没有选择您的 application.properties 文件(应该在您的类路径中)。
  • 那么你的环境变量没有被你的应用程序加载。您如何将它们加载到项目中?
  • 在哪里可以解决您的问题?

标签: spring spring-boot


【解决方案1】:

在此处查看此文档: https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html

尝试命名您的环境变量:

SPRING_DATASOURCE_URL

SPRING_DATASOURCE_USERNAME

SPRING_DATASOURCE_PASSWORD

更新:

Spring boot 确实正确选择了环境变量,请参见下面的测试。

package com.example.environment_vars;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

import java.util.Map;      // Import this for systemEnvironment

@SpringBootApplication
public class EnvironmentVarsApplication {

    @Value("#{systemEnvironment['ENV_VAR'] ?: 'Default_value'}")
    private String envVar;
    
    @Bean
    public CommandLineRunner commandLineRunner() {
        return new CommandLineRunner() {
            @Override
            public void run(String[] arg0) throws Exception {
                System.out.println(envVar);
            }
        };
    }
    
    public static void main(String[] args) {
        SpringApplication.run(EnvironmentVarsApplication.class, args);
    }
}

这将打印出环境变量 ENV_VAR 的值,如果该值不存在,它将打印 Default_Value

@Value 注入整个项目可访问的值。

【讨论】:

  • 我需要在属性文件中指定默认值还是环境变量就足够了?
  • 根据文档,环境变量应该足够了,不过我还没有测试过。给它一个快速测试,如果它不起作用,我们可以尝试另一种方法。
  • 如果我尝试在属性文件中不使用默认值,我会收到一条错误消息,指出应用程序无法启动并且描述为 Cannot determine embedded database driver class for database type NONE
  • 你确定导出环境变量了吗?在上面的更新中,我测试并确认环境变量是由 spring boot 拾取的。你是在tomcat还是其他web服务器上运行?这可能会影响对环境变量的访问。
  • @AleksandrErokhin 您可以在此处找到转换文档:docs.spring.io/spring-boot/docs/current/reference/html/…
【解决方案2】:

您可以使用DataSource配置文件并使用System.getEnv("ENV_VARIABLE")方法获取环境变量。

首先,您应该删除以“spring.datasource”开头的属性。在 application.properties 中。然后包含这个准备就绪的配置文件:

import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;

@Configuration
class JpaConfig {

    @Bean
    public DataSource getDataSource() {
        return DataSourceBuilder.create()
                .driverClassName("com.mysql.cj.jdbc.Driver")
                .url(getDataSourceUrl())
                .username(System.getenv("DB_USERNAME"))
                .password(System.getenv("DB_PASSWORD"))
                .build();
    }

    private String getDataSourceUrl() {
        return "jdbc:mysql://"
                + System.getenv("DB_HOST") + "/"
                + System.getenv("DB_NAME")
                + "?allowPublicKeyRetrieval=true&useSSL=false&serverTimezone=UTC&useLegacyDatetimeCode=false";
    }
}

【讨论】:

    猜你喜欢
    • 2019-08-03
    • 1970-01-01
    • 2017-09-06
    • 1970-01-01
    • 2016-11-15
    • 2018-12-21
    • 2022-01-25
    • 2019-08-03
    • 2014-09-07
    相关资源
    最近更新 更多