【问题标题】:Spring boot external configuration in standalone jetty独立码头中的Spring Boot外部配置
【发布时间】:2017-05-04 20:33:33
【问题描述】:

我正在构建一个 Spring Boot 应用程序。我想在外部配置我的数据库属性,所以任何人都可以从任何机器上运行 war 文件。如何在外部配置 application.properties?我正在关注此文档http://docs.spring.io/autorepo/docs/spring-boot/1.0.1.RELEASE/reference/html/boot-features-external-config.html

所以我在 jetty 的主目录中创建了一个 app.properties 文件。

spring.datasource.url=jdbc:sqlserver://mymachine:1433;databasename=TESTDB
spring.datasource.driver-class-name=com.microsoft.sqlserver.jdbc.SQLServerDriver
spring.datasource.username=someuser
spring.datasource.password=somepass

并试图通过码头运行war文件,但由于某种原因它没有检测到application.properties。

java -jar ../start.jar --spring.config.location=file:///E:/Tools/jetty-distribution-9.3.12.v20160915/demo-base/webapps/app.properties

当我运行上面的命令时,我在码头出现以下错误

Caused by:
java.lang.IllegalArgumentException: Property 'driverClassName' must not be empty
        at org.springframework.util.Assert.hasText(Assert.java:168)
        at org.springframework.jdbc.datasource.DriverManagerDataSource.setDriverClassName(DriverManagerDataSource.java:1
24)
        at com.abc.mycompany.sts.config.settings.PersistenceContext.dataSource(PersistenceContext.java:55)
        at com.abc.mycompany.sts.config.settings.PersistenceContext$$EnhancerBySpringCGLIB$$368bb66a.CGLIB$dataSource$2
(<generated>)
        at com.abc.mycompany.sts.config.settings.PersistenceContext$$EnhancerBySpringCGLIB$$368bb66a$$FastClassBySpring
CGLIB$$25ca0903.invoke(<generated>)
        at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
        at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(Configurati
onClassEnhancer.java:356)
        at com.abc.mycompany.sts.config.settings.PersistenceContext$$EnhancerBySpringCGLIB$$368bb66a.dataSource(<genera
ted>)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy
.java:162)
        at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolv
er.java:588)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(Ab
stractAutowireCapableBeanFactory.java:1128)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutow
ireCapableBeanFactory.java:1022)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCap
ableBeanFactory.java:512)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapab
leBeanFactory.java:482)

这是我码头的目录结构

E:\Tools\jetty-distribution-9.3.12.v20160915\demo-base\webapps

在命令行上,我通过转到演示库并运行命令来启动码头

java -jar ../start.jar --spring.config.location=file:///E:/Tools/jetty-distribution-9.3.12.v20160915/demo-base/webapps/app.properties

bean 如下所示,我正在尝试从外部 application.properties 文件访问属性

@Bean
public DataSource dataSource() {
    final DriverManagerDataSource dataSource = new DriverManagerDataSource();            
    dataSource.setDriverClassName(env.getProperty(ConfigConstants.DATABASE_DRIVER_CLASS_NAME));
    dataSource.setUrl(env.getProperty(ConfigConstants.DATABASE_URL));
    dataSource.setUsername(env.getProperty(ConfigConstants.DATABASE_USERNAME));
    dataSource.setPassword(env.getProperty(ConfigConstants.DATABASE_PASSWORD));

    return dataSource;
}

这找不到我的 app.properties 文件。我错过了什么?

【问题讨论】:

  • 你可以试试 spring.datasource.driverClassName(不带连字符)吗?
  • @Lucky - 这没有意义,因为当属性文件在 jar 中时,相同的属性会起作用
  • 仍需要更多信息。例如,您能告诉我们 application.properties 应该驻留的目录/文件结构吗?
  • @pczeus - 我下载了 jetty,它位于路径 E:\Tools 上。您可以看到我添加的有关我尝试启动码头的目录的更多信息

标签: spring-boot jetty


【解决方案1】:

我看到您使用 env 属性来初始化数据源,我会为您推荐另一种解决方案。

命题一:可以在启动时设置属性值,如:

java -jar ../start.jar --spring.datasource.url=jdbc:sqlserver://mymachine:1433;databasename=TESTDB --spring.datasource.driver-class-name=com.microsoft.sqlserver.jdbc.SQLServerDriver --spring.datasource.username=someuser --spring.datasource.password=somepass

或者,如果您想要掩码属性名称,请定义您自己的属性。您必须将以下 application.properties 文件打包到您的 jar 中:

spring.datasource.url=${APP_DB_URL}
spring.datasource.driver-class-name=${APP_DB_DRIVER_CLASS}
spring.datasource.username=${APP_DB_USERNAME}
spring.datasource.password=${APP_DB_PASSWORD}

接下来。在运行应用程序设置环境属性之前。在 *nix 平台上:

export APP_DB_URL=jdbc:sqlserver://mymachine:1433;databasename=TESTDB
export APP_DB_DRIVER_CLASS=com.microsoft.sqlserver.jdbc.SQLServerDriver
export APP_DB_USERNAME=someuser
export APP_DB_PASSWORD=somepass

在windows平台上:

set APP_DB_URL=jdbc:sqlserver://mymachine:1433;databasename=TESTDB
set APP_DB_DRIVER_CLASS=com.microsoft.sqlserver.jdbc.SQLServerDriver
set APP_DB_USERNAME=someuser
set APP_DB_PASSWORD=somepass

最后,只运行你的 jar,不带任何参数:

java ../start.jar

希望这篇文章对你有所帮助。

【讨论】:

  • 我不能在 jar 中包含 application.properties,这就是为什么我尝试外部配置,我可以在任何环境中运行我的 war 文件
  • 好的,第一个命题(--spring.datasource.url= ...)怎么样,对你有帮助吗?您可以通过这种方式覆盖所需的属性。
  • 不知道发生了什么,但突然你建议的第一个选项不再起作用,我得到了与我在这个问题中报告的相同的错误
  • 项目/版本/环境有什么变化吗?你能显示整个启动命令吗?
  • Konstantin - 我决定采用方法 2,不知道为什么方法 1 突然停止工作。 java -jar ../start.jar --spring.datasource.url=jdbc:sqlserver://mymachine:1433;databasename=TESTDB --spring.datasource.driver-class-name=com.microsoft.sqlserver.jdbc。 SQLServerDriver --spring.datasource.username=someuser --spring.datasource.password=somepass
【解决方案2】:

将你的 application.properties 文件放在JETTY_HOME/resources 文件夹下并添加

--module=resources

start.ini 文件的行。

第二个将资源文件夹添加到类路径,因此该目录下的每个文件都将位于您的 webapp 的类路径中。

这应该可行。

【讨论】:

    【解决方案3】:
    --spring-config-location
    

    不是正确的属性名称。该属性使用点表示法,而不是连字符。

    试试:

    --spring.config.location
    

    有关详细信息,请参阅文档中的第 24.3 节:http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html

    此外,您应该指向 application.properties 所在的目录,而不是特定文件。这可能会有所帮助,但当您稍后想要指定配置文件时会更有用。然后 Spring Boot 可以根据配置文件选择正确的属性文件。例如:

    --spring.config.location=file:///E:/jetty/demo-base/webapps/
    

    如果您在此目录中有多个文件,例如:

    application.properties
    application-dev.properties 
    application-prod.properties
    

    你可以添加

    --spring.profiles.active=prod
    

    选择产品属性。

    【讨论】:

    • 是的,我现在试过了,但它仍然给我同样的错误,关于 driverClassName must not be empty。我正在从属性文件中填充 driverClassname 属性
    • 您能否更新您的帖子并提供您收到的堆栈跟踪和错误信息?
    • 我只有一个文件。它被命名为 app.properties 而不是 application.properties。文件名没有任何区别。我犯了同样的错误。如果我在我的战争中使用相同的文件,它工作正常。也指向目录而不是文件,我得到同样的错误
    【解决方案4】:

    “file:”协议后的文件路径中的斜杠太多,也应该使用反斜杠:

    --spring.config.location=file:E:\Tools\jetty-distribution-9.3.12.v20160915\demo-base\webapps\app.properties

    【讨论】:

    • 您确定使用斜线吗? Spring 的网站上是这样说的
    猜你喜欢
    • 2015-05-31
    • 2017-11-26
    • 1970-01-01
    • 2021-01-05
    • 2019-08-17
    • 2014-10-10
    • 1970-01-01
    • 1970-01-01
    • 2016-07-29
    相关资源
    最近更新 更多