【问题标题】:How to externally provide mysql host to spring boot while executing JAR执行JAR时如何从外部提供mysql主机到spring boot
【发布时间】:2019-03-06 23:21:35
【问题描述】:

我有一个使用 MySQL 数据库的 java Spring boot 项目。我有以下application.properties 文件来指定MySQL url、用户和密码:

spring.datasource.url=jdbc:mysql://${DB_HOST}:${DB_PORT}/${DB_NAME}
spring.datasource.username=${MYSQL_USER}
spring.datasource.password=${MYSQL_PASSWORD}

使用这个属性文件,如果我编辑运行配置并在环境选项卡中设置DB_HOSTDB_PORTDB_NAMEMYSQL_USERMYSQL_PASSWORD 的值,我可以从 Eclipse 运行应用程序运行它..一切正常。

但现在我想在服务器上运行它,方法是生成一个 JAR 并在运行时将这些值从命令行传递到 Jar。所以,我创建了一个这样的 Jar 文件:

/gradlew clean build bootJar -DDB_HOST=mock -DDB_PORT=mock -DDB_NAME=mock \
-Dmysql_user=mock \
-Dmysql_password=mock

这成功生成了可执行的Jar文件..然后我尝试像这样运行生成的jar文件:

java -jar build/libs/MyApplication.jar -Ddb_host=localhost \
-Ddb_port=3306 \
-Ddb_name=my_db \
-Dmysql_user=root \
-Dmysql_password=root

但它给出了以下错误:

...
Failed to parse the host:port pair '${DB_HOST}:${DB_PORT}'
...
java.lang.NumberFormatException: For input string: "${DB_PORT}"
...

这意味着它实际上并没有在运行时替换值。

我该如何解决这个问题?

编辑:我还尝试使用存档实用程序打开 jar 并看到 application.properties 文件。它包含以下行:

spring.datasource.url=jdbc:mysql://${DB_HOST}:${DB_PORT}/${DB_NAME}

这意味着这些值应该在运行时更新。但它不是

【问题讨论】:

  • 只是不要在application.properties 中包含这些条目并直接设置-Dspring.datasource.username。在失败的情况下,检查是否需要将这些属性放在-jar 子句之前。
  • 试过了,也试过在 -jar 之前给 -D 部分..没用。这次它给出了错误:java.sql.SQLException: Access denied for user ''@'localhost' (using password: NO) 所以,我认为它根本没有从命令行获取这些值。
  • 您可以尝试将这些属性添加到外部文件中,并使用 @PropertySource 在 Spring 配置类中使用它。您还可以根据部署应用程序的方式将这些添加到环境变量中。
  • 使用配置文件将是我认为的最佳实践。然后在你的 app.properties 中运行这些配置文件或使用环境变量(没有 ${..} 东西)注入它们
  • db_hostDB_HOST 不同。在 -D 参数中使用大写。

标签: java mysql spring spring-boot


【解决方案1】:

我最终能够通过添加 DatasourceConfig 类并以编程方式设置值来使其工作。

我从application.property 文件中删除了所有spring.datasource.* 值,然后创建了一个新类:

@Configuration
@EnableTransactionManagement
@PropertySource("classpath:application.properties")
public class DatasourceConfig {

  @Bean
  @Primary
  public DataSource dataSource() {
    DriverManagerDataSource dataSource = new DriverManagerDataSource();
    dataSource.setUrl(System.getProperty("MYSQL_URL"));
    dataSource.setUsername(System.getProperty("MYSQL_USER"));
    dataSource.setPassword(System.getProperty("MYSQL_PASSWORD"));
    return dataSource;
  }

}

这允许您在运行时在外部将数据源、用户名和密码配置为 VM 参数。

MYSQL_URL,MYSQL_USER,MYSQL_PASSWORD 的值在构建时传递给 gradle 命令:

./gradlew clean build bootJar -DMYSQL_URL=mock -DMYSQL_USER=mock -DMYSQL_PASSWORD=mock

,类似于java 命令,同时像这样运行 jar:

java -jar build/libs/MyApplication.jar -DMYSQL_URL=jdbc:mysql://localhost:3306/my_db -DMYSQL_USER=root -DMYSQL_PASSWORD=root

【讨论】:

    【解决方案2】:

    您只需在运行 jar 之前将这些字段公开为环境变量。

    对于 Linux:

    $ export DB_HOST=localhost
    $ export DB_PORT=3306
    $ export DB_NAME=my_db
    $ export MYSQL_USER=root
    $ export MYSQL_PASSWORD=root
    $ java -jar build/libs/MyApplication.jar
    

    【讨论】:

      猜你喜欢
      • 2016-12-20
      • 2019-07-11
      • 2016-04-03
      • 1970-01-01
      • 2020-10-04
      • 2017-08-21
      • 2017-12-27
      • 1970-01-01
      • 2020-11-16
      相关资源
      最近更新 更多