环境变量和@Value 不能在 Spring Boot 上一起工作

Lui*_* E. 2 java spring docker spring-boot docker-compose

我有一个 Spring 启动应用程序,它连接到一个用作缓存的 Redis 实例。当我在开发环境中时,我有以下内容:

---

spring:
  profiles: default
redis: 
  host: localhost
  port: 6379
Run Code Online (Sandbox Code Playgroud)

而我的缓存配置类是这样的:

@Configuration
@EnableCaching
public class CacheConfiguration {

   @Value("${redis.host}") 
   String redisHost;

   @Value("${redis.port}") 
   int redisPort;
Run Code Online (Sandbox Code Playgroud)

在生产中,这个应用程序是 Dockerized,我有以下docker-compose.yml文件:

redis: 
  image: tutum/redis
  ports:
    - "6379:6379"
  volumes:
    - /data
app: 
  build: .
  ports:
    - "8080:8080"
  links:
    - redis
Run Code Online (Sandbox Code Playgroud)

application.yml是:

---

spring:
  profiles: docker
redis: 
  host: redis
  port: 6379
Run Code Online (Sandbox Code Playgroud)

要在 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"
Run Code Online (Sandbox Code Playgroud)

出于某种原因,Spring Boot 正在读取redis.portas tcp://172.17.0.3:6379。因此,对于测试建议,我@ValueCacheConfiguration类中删除了注释 ,并将其手动设置redis为主机和6379端口,并且它工作正常。似乎在使用环境变量和时@Value,Spring 迷路了。有人有想法吗?

Ali*_*ani 7

基于Docker 文档

Compose 使用 Docker 链接向彼此公开服务容器。每个链接的容器都会注入一组环境变量,每个环境变量 都以容器的大写名称开头

Docker Compose 将使用name_PORT格式创建一个表示容器完整 URL的环境变量,例如.REDIS_PORT=tcp://172.17.0.5:6379

并根据您的docker-compose.yml文件:

redis: 
  image: tutum/redis
  ports:
    - "6379:6379"
  volumes:
    - /data
Run Code Online (Sandbox Code Playgroud)

您将拥有一个名为 的环境变量REDIS_PORT,其值等于tcp://172.17.0.3:6379. 由于 OS 环境变量在特定于 Profile 的应用程序属性方面具有更高的优先级,因此Spring Boot 会选择REDIS_PORT超过的值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.name为任何争议较小的名称。

有点偏离主题,但只是引用tutum-docker-redis Github 存储库

此图片将很快被弃用。请使用docker官方镜像:https : //hub.docker.com/_/redis/