我们正在开发一个Spring Boot web应用程序,我们使用的数据库是MySQL;

我们的设置是我们首先在本地测试它(意味着我们需要在我们的PC上安装MySQL); 然后我们推送到Bitbucket; Jenkins自动检测到新的推送到Bitbucket,并在其上进行构建(为了让Jenkins mvn构建通过,我们还需要在运行Jenkins的虚拟机上安装MySQL)。 如果Jenkins构建通过,我们将代码推送到OpenShift上的应用程序(在Jenkins上使用OpenShift部署插件)。

你可能已经发现了,我们的问题是:

在应用程序中。属性我们不能硬编码MySQL信息。由于我们的项目将在3个不同的地方运行(local、Jenkins和OpenShift),我们需要在应用程序中使数据源字段动态。属性(我们知道有不同的方法,但我们现在正在研究这个解决方案)。 spring.datasource.url = spring.datasource.username = spring.datasource.password =

我们提出的解决方案是在本地和Jenkins VM中创建系统环境变量(命名方式与OpenShift相同),并分别为它们分配正确的值:

export OPENSHIFT_MYSQL_DB_HOST="jdbc:mysql://localhost"
export OPENSHIFT_MYSQL_DB_PORT="3306"
export OPENSHIFT_MYSQL_DB_USERNAME="root"
export OPENSHIFT_MYSQL_DB_PASSWORD="123asd"

我们已经这么做了,而且很有效。我们还检查了Map<String, String> env = System.getenv();环境变量可以像这样变成Java变量:

String password = env.get("OPENSHIFT_MYSQL_DB_PASSWORD");   
String userName = env.get("OPENSHIFT_MYSQL_DB_USERNAME");   
String sqlURL = env.get("OPENSHIFT_MYSQL_DB_HOST"); 
String sqlPort = env.get("OPENSHIFT_MYSQL_DB_PORT");

现在,我们需要在应用程序中使用这些java变量。属性,这就是我们遇到的麻烦。

我们需要在哪个文件夹中以及如何为应用程序分配密码、userName、sqlURL和sqlPort变量。属性以便能够看到它们以及我们如何在application。Properties中包含它们?

我们尝试了很多东西,其中之一是:

spring.datasource.url = ${sqlURL}:${sqlPort}/"nameofDB"
spring.datasource.username = ${userName}
spring.datasource.password = ${password}

到目前为止还没有。我们可能没有将这些环境变量放在正确的类/文件夹中,或者在application.properties中错误地使用了它们。


当前回答

使用Spring context 5.0,我通过下面的注释成功地实现了基于系统环境加载正确的属性文件

@PropertySources({
    @PropertySource("classpath:application.properties"),
    @PropertySource("classpath:application-${MYENV:test}.properties")})

这里MYENV值是从系统环境中读取的,如果系统环境不存在,那么默认的测试环境属性文件将被加载,如果我给出错误的MYENV值-它将无法启动应用程序。

注意:对于每个概要文件,您想要维护-您将需要制作一个应用程序-[概要文件]。虽然我使用的是Spring context 5.0,而不是Spring boot,但我相信这也适用于Spring 4.1

其他回答

这是对一些评论的回应,因为我的声誉不够高,不能直接评论。

只要还没有加载应用程序上下文,您就可以在运行时指定概要文件。

// Previous answers incorrectly used "spring.active.profiles" instead of
// "spring.profiles.active" (as noted in the comments).
// Use AbstractEnvironment.ACTIVE_PROFILES_PROPERTY_NAME to avoid this mistake.

System.setProperty(AbstractEnvironment.ACTIVE_PROFILES_PROPERTY_NAME, environment);
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("/META-INF/spring/applicationContext.xml");

Flyway不识别应用程序中的直接环境变量。属性(Spring-Boot V2.1)。 如

spring.datasource.url=jdbc:mysql://${DB_HOSTNAME}:${DB_PORT}/${DB_DATABASE}
spring.datasource.username=${DB_USER}
spring.datasource.password=${DB_PASS}

为了解决这个问题,我做了这个环境变量,通常我创建文件.env:

SPRING_DATASOURCE_URL=jdbc:mysql://127.0.0.1:3306/place
SPRING_DATASOURCE_USERNAME=root
SPRING_DATASOURCE_PASSWORD=root

并导出变量到我的环境:

export $(cat .env | xargs)

最后运行命令

mvn spring-boot:run

或者运行jar文件

java -jar target/your-file.jar

这里还有另一种方法:https://docs.spring.io/spring-boot/docs/2.1.0.RELEASE/maven-plugin/examples/run-env-variables.html

你不需要使用java变量。若要包含系统环境变量,请在应用程序中添加以下内容。属性文件:

spring.datasource.url = ${OPENSHIFT_MYSQL_DB_HOST}:${OPENSHIFT_MYSQL_DB_PORT}/"nameofDB"
spring.datasource.username = ${OPENSHIFT_MYSQL_DB_USERNAME}
spring.datasource.password = ${OPENSHIFT_MYSQL_DB_PASSWORD}

但是@Stefan Isele建议的方法更可取,因为在这种情况下,你只需要声明一个env变量:spring.profiles.active。Spring将通过application-{profile-name}自动读取相应的属性文件。属性模板。

我和问题的作者面临着同样的问题。对于我们的案例,这个问题的答案是不够的,因为我的团队中的每个成员都有不同的本地环境,我们肯定需要.gitignore具有不同的db连接字符串和凭据的文件,这样人们就不会错误地提交公共文件并破坏其他人的db连接。

最重要的是,当我们遵循下面的步骤时,它很容易部署到不同的环境中,作为额外的奖励,我们根本不需要在版本控制中保留任何敏感信息。

从具有参数的PHP Symfony 3框架中获得思想。Yml (.gitignored)和parameters.yml.dist(这是通过composer install创建第一个样本),

我结合以下答案中的知识做了以下工作:https://stackoverflow.com/a/35534970/986160和https://stackoverflow.com/a/35535138/986160。

从本质上讲,这让您可以自由地使用spring配置的继承,并通过顶部的配置以及任何额外的敏感凭证选择活动配置文件,如下所示:

application.yml.dist (sample)

    spring:
      profiles:
        active: local/dev/prod
      datasource:
        username:
        password:
        url: jdbc:mysql://localhost:3306/db?useSSL=false&useLegacyDatetimeCode=false&serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8

应用程序。yml(。Gitignore-d开发服务器)

spring:
  profiles:
    active: dev
  datasource:
    username: root
    password: verysecretpassword
    url: jdbc:mysql://localhost:3306/real_db?useSSL=false&useLegacyDatetimeCode=false&serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8

应用程序。yml(。Gitignore-d在本地机器上)

spring:
  profiles:
    active: dev
  datasource:
    username: root
    password: rootroot
    url: jdbc:mysql://localhost:3306/xampp_db?useSSL=false&useLegacyDatetimeCode=false&serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8

application-dev。Yml(额外环境特定属性不敏感)

spring:
  datasource:
    testWhileIdle: true
    validationQuery: SELECT 1
  jpa:
    show-sql: true
    format-sql: true
    hibernate:
      ddl-auto: create-drop
      naming-strategy: org.hibernate.cfg.ImprovedNamingStrategy
    properties:
      hibernate:
        dialect: org.hibernate.dialect.MySQL57InnoDBDialect

使用.properties也可以做到这一点

如果属性文件被外部化为环境变量,那么运行配置可以添加到IDE中:

--spring.config.additional-location={PATH_OF_EXTERNAL_PROP}