我有一个Spring启动应用程序,它连接到一个用作缓存的Redis实例。当我在开发环境中时,我有以下内容:
---
spring:
profiles: default
redis:
host: localhost
port: 6379
我的缓存配置类是这样的:
@Configuration
@EnableCaching
public class CacheConfiguration {
@Value("${redis.host}")
String redisHost;
@Value("${redis.port}")
int redisPort;
在制作中,这个应用程序是Dockerized,我有以下docker-compose.yml
文件:
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
运行,但是当应用程序启动时,会发生以下错误:
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
。因此,对于测试建议,我从@Value
类中删除了CacheConfiguration
注释,并将其手动设置为redis
作为主机,将6379
设置为端口并且它可以正常工作。似乎在使用环境变量和@Value
时,Spring会迷失方向。有人有想法吗?
答案 0 :(得分:4)
Compose使用Docker链接将服务容器公开给一个 另一个。每个链接的容器都注入一组环境变量, 每个以容器的大写名称开头。
Docker Compose将使用 name_PORT 格式创建表示容器的完整网址的环境变量,例如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环境变量在特定于配置文件的应用程序属性方面具有更多优先级,因此Spring Boot将获取{{ 1}}超过REDIS_PORT
的值,因此错误:
引起: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”
作为此问题的解决方法,您应该使用您的端口值覆盖redis.port
环境变量,或者将您的配置名称从REDIS_PORT
重命名为更少争议的内容。
有点偏离主题但只引用redis.name
Github repository:
此图片即将弃用。请使用码头官员 图片:https://hub.docker.com/_/redis/