环境变量和@Value无法在Spring Boot

时间:2016-05-08 16:44:27

标签: java spring docker spring-boot docker-compose

我有一个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会迷失方向。有人有想法吗?

1 个答案:

答案 0 :(得分:4)

基于Docker documentation

  

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/