在 Docker 容器中运行时,从属性文件实例化 Spring 配置类时出错



当我在Tomcat 8 Docker容器中运行我的Web应用程序时,我得到了一个NumberFormatException。当 Spring 尝试实例化 MongoConfig 类时会发生此错误,该类注入@Values取自类路径属性文件。属性文件中的属性如下所示:

mongodb.host=mongodb
mongodb.database=mydatabase
mongodb.port=27017
mongodb.username=myusername
mongodb.password=mypassword

在MongoConfig文件中,当它到达这一点时,它会被NumberFormatException所困扰:

@Value("${mongodb.port}")
private int port;

根据错误,它选择"tcp://172.17.0.2:27017"作为它试图硬塞进端口的输入,尽管属性文件清楚地提供了端口,而没有任何其他内容,如 IP 地址。它被拾取的 IP 地址是分配给 mongodb 容器的地址(一个单独的 Docker 容器,没有多余的装饰,只有带有 --name mongodb 的 mongodb:latest ,然后在 Tomcat 容器的运行命令中被链接为 mongodb:mongodb)。如果你进入正在运行的Tomcat容器并查看/etc/hosts,你会看到mongodb的条目,它似乎是可以从Tomcat容器中访问的。

为什么 Spring 会选取整个 tcp 地址,包括 IP 和端口,当它在属性文件中单独提供端口时?我应该如何处理?

更新 - 错误是:"创建名为'com.mydomain.myproject.config.MongoConfig'的bean时出错:通过字段'port'表示的不满意依赖关系:无法将类型[java.lang.String]的值转换为所需的类型[int];嵌套异常是java.lang.NumberFormatException:对于输入字符串:"tcp://172.17.0.2:27017";嵌套异常是 org.springframework.beans.TypeMismatchException:无法将 [java.lang.String] 类型的值转换为所需的类型 [int];嵌套异常是java.lang.NumberFormatException:对于输入字符串:"tcp://172.17.0.2:27017"

似乎mongodb.port在容器中被覆盖了。将端口号更改为 99999 没有任何操作。将属性名称更改为"mylovely.port"然后给了我们一个错误,抱怨端口超出范围,并显示它是99999。将其修改回 27017,然后给了我一个正在运行的 Web 应用程序,没有崩溃。剩下的问题是,什么覆盖了这个值,为什么一个名为port的属性有一个完整的地址?是不是 --link 选项不仅在 tomcat 容器的/etc/hosts 中设置了一个条目,而且还创建了某种名为 mongodb 的全局变量或属性,无论它之后出现什么,它总是返回完整的地址?

Docker 设置一个优先于配置文件的环境变量MONGODB_PORT。您可以通过检查(docker inspect)容器来证明这一点,或者,如果它不起作用,则通过使用docker exec并在容器中执行env命令来证明这一点。

更新:如何解决?首先,阅读有关PropertySource抽象的信息。接下来,您将发现环境变量值可以被系统属性 (-Dmongodb.port=27017覆盖。我也尝试使用PropertyOverrideConfigurer但我不确定它是否会起作用。

最新更新