在Spring Boot上环境变量和@Value不能一起使用 [英] Environment variables and @Value can't work together on Spring Boot
问题描述
我有一个Spring启动应用程序,该应用程序连接到充当缓存的Redis实例。在开发环境中时,我有以下内容:
I have a Spring boot app that connects to a Redis instance that works as a cache. When I'm in dev environment, I have the following:
---
spring:
profiles: default
redis:
host: localhost
port: 6379
我的缓存配置类是这样的:
And my cache configuration class is like this:
@Configuration
@EnableCaching
public class CacheConfiguration {
@Value("${redis.host}")
String redisHost;
@Value("${redis.port}")
int redisPort;
在生产中,此应用程序已被Docker化,并且我有以下 docker- compose.yml
文件:
In production, this app is Dockerized, and I have the following docker-compose.yml
file:
redis:
image: tutum/redis
ports:
- "6379:6379"
volumes:
- /data
app:
build: .
ports:
- "8080:8080"
links:
- redis
而 application.yml
是:
---
spring:
profiles: docker
redis:
host: redis
port: 6379
要在Docker上启动应用程序,我需要运行 -Dspring.profiles.active = docker
,但是在应用程序启动时,会发生以下错误:
To start the app on Docker, I run with -Dspring.profiles.active=docker
, but when the app is starting up, the following error happens:
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private int com.inkdrop.config.cache.CacheConfiguration.redisPort; nested exception is org.springframework.beans.TypeMismatchException: Failed to convert value of type [java.lang.String] to required type [int]; nested exception is java.lang.NumberFormatException: For input string: "tcp://172.17.0.3:6379"
由于某种原因,Spring Boot将 redis.port
读为 tcp://172.17.0.3:6379
。因此对于测试建议,我从 CacheConfiguration
类中删除了 @Value
批注,并将其手动设置为 redis
作为主机, 6379
作为端口,它可以正常工作。好像在使用环境变量和 @Value
时,Spring迷路了。有人有想法吗?
For some reason, Spring Boot is reading the redis.port
as tcp://172.17.0.3:6379
. So for tests proposes, I removed the @Value
annotations from CacheConfiguration
class, and set it manually to redis
as host and 6379
as port and it worked. Seems like when using environment variables and @Value
, Spring get lost. Anyone have an idea?
推荐答案
基于 Docker文档:
Compose使用Docker链接公开服务容器到一个
每个链接的容器都会注入一组环境变量,
每个变量都以容器的大写字母开头。
Docker Compose将使用 name_PORT 格式创建表示容器的完整URL 的环境变量,例如 REDIS_PORT = tcp://172.17.0.5:6379
。
Docker Compose would create an Environment Variable representing the Full URL of the container using name_PORT format, e.g. REDIS_PORT=tcp://172.17.0.5:6379
.
并基于您的 docker-compose.yml
文件:
redis:
image: tutum/redis
ports:
- "6379:6379"
volumes:
- /data
您将拥有一个名为 REDIS_PORT
的环境变量,其值等于 tcp://172.17.0.3:6379
。由于OS环境变量相对于Profile特定的应用程序属性具有更高的优先级,因此Spring Boot会在上使用
,因此出现错误: REDIS_PORT
值redis.port
You would have an Environment Variable named REDIS_PORT
with a value equals to tcp://172.17.0.3:6379
.Since OS environment variables have more precedence with respect to Profile-specific application properties, Spring Boot would pick up the REDIS_PORT
value over redis.port
, hence the error:
原因:org.springframework.beans.factory.BeanCreationException:
无法自动连线字段:private int
com.inkdrop.config.cache.CacheConfiguration.redisPort;嵌套的
异常是org.springframework.beans.TypeMismatchException:
无法将[java.lang.String]类型的值转换为所需的[int]类型;
嵌套异常是java.lang.NumberFormatException:对于输入字符串:
tcp://172.17.0.3:6379
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private int com.inkdrop.config.cache.CacheConfiguration.redisPort; nested exception is org.springframework.beans.TypeMismatchException: Failed to convert value of type [java.lang.String] to required type [int]; nested exception is java.lang.NumberFormatException: For input string: "tcp://172.17.0.3:6379"
作为解决此问题的方法,您应该使用端口值覆盖 REDIS_PORT
环境变量,或者从 redis重命名配置名称。 .name
到没有争议的地方。
As a workaround for this problem, you either should override the REDIS_PORT
environment variable with your port value or rename your config name from redis.name
to anything less controversial.
有点麻烦,但只是引用 tutum-docker-redis
Github存储库:
Kinda off topic but just quoting from tutum-docker-redis
Github repository:
此图片将很快被弃用。请使用docker美元
官方图片: https://hub.docker.com/_/redis /
这篇关于在Spring Boot上环境变量和@Value不能一起使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!