在SpringBoot中读取环境变量

87

SpringBoot 中读取 环境变量 的最佳方式是什么?
在 Java 中,我使用以下代码实现:

String foo = System.getenv("bar");

使用@Value注解是否可以做到呢?

9个回答

91

引用文档

Spring Boot允许您将配置外部化,以便在不同的环境中使用相同的应用程序代码。 您可以使用属性文件、YAML文件、环境变量和命令行参数来外部化配置。 可以使用@Value注释将属性值直接注入到bean中,也可以通过Spring的Environment抽象访问或绑定到经过结构化处理的对象上,这些对象使用@ConfigurationProperties

因此,由于Spring Boot允许您使用环境变量进行配置,并且由于Spring Boot还允许您使用@Value从配置中读取属性,所以答案是肯定的。


例如,以下内容将产生相同的结果:

@Component
public class TestRunner implements CommandLineRunner {
    @Value("${bar}")
    private String bar;
    private final Logger logger = LoggerFactory.getLogger(getClass());
    @Override
    public void run(String... strings) throws Exception {
        logger.info("Foo from @Value: {}", bar);
        logger.info("Foo from System.getenv(): {}", System.getenv("bar")); // Same output as line above
    }
}

如果我想在 @Entity 类中使用它,例如用于 getter,该怎么办? - nonNumericalFloat

65
您可以使用@Value注释来完成此操作:
@Value("${bar}")
private String myVariable;

如果未找到,您还可以使用冒号来提供默认值:

@Value("${bar:default_value}")
private String myVariable;

2
仅在已初始化的组件中工作,不能在静态 main 函数的主类中工作。 - e-info128

25

下面是三种可以用来访问名为MY_SECRET的系统环境变量的“占位符”语法:

@Value("${MY_SECRET:aDefaultValue}")
private String s1;

@Value("#{environment.MY_SECRET}")
private String s2;

@Value("${myApp.mySecretIndirect:aDefaultValue}") // via application property
private String s3;

在第三种情况下,占位符引用了一个已经从系统环境中在属性文件中初始化的应用程序属性:

myApp.mySecretIndirect=${MY_SECRET:aDefaultValue}

要让@Value起作用,必须在实时的@Component(或类似组件)内使用。如果您希望在单元测试期间使其正常工作,则还有其他注意事项--请参阅我的答案Why is my Spring @Autowired field null?


8
在使用environment.时,请注意不同的标点符号 #{${} - Brent Bradburn
1
我认为你打错了,@Value("#{environment.MY_SECRET}") 应该用 $ 符号。 - dgraf
@dgraf,请看我之前的评论 - 这是有意为之的。这是一种比较隐晦的功能,但你可以通过查找 Spring Expression Language (SpEL) 来找到相关文档。 - Brent Bradburn

20
或者,您可以使用org.springframework.core.env.Environment接口来访问环境变量(注意:这仅适用于已初始化的Spring组件):
import org.springframework.core.env.Environment;

@Autowired
private Environment env;

//...

System.out.println(env.getProperty("bar"));

阅读更多...


3
仅适用于已初始化的Spring组件,无法在@SpringBootApplication类的主静态函数中工作。 - e-info128

1

0

您可以将环境变量放置在 application.yml/application.properties 文件中,然后可以使用 @Value 注释获取该值。但是为了使用 @Value 注释,您的类应该是一个 bean,并且应该用 @Component 注释进行注解。您也可以为该变量提供默认值。

@Component
@NoArgsConstructor
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public class MyClass {
 
@Value("${something.variable:<default-value>}")
private String myEnvVariable;

}
    

0

您可以在@Component@Service类中使用@Value注释。

有时,如果它是普通类,则无法正常工作。

例如:

@Component
public class Testclass{
    @Value("${MY_SECRET:aDefaultValue}")
    private String test1;

    @Value("#{environment.MY_SECRET}")
    private String test2;

    @Value("${myApp.mySecretIndirect:aDefaultValue}")
    private String test3;

    //to get the properties list which are in "," separated
    @Value("${my.list.of.strings}")
    private List<String> myList;
}

0
在极少数情况下,如果你想在Spring的静态`main`方法中访问环境参数,你必须先让Spring应用程序构建,然后使用`ApplicationContext`来访问`environment`。类似这样的操作。
public static void main(String[] args) {
            
    ApplicationContext applicationContext = new SpringApplicationBuilder(MyApp.class).run(args);
    Environment environment = applicationContext.getEnvironment();
    System.out.println(environment.getProperty("spring.application.name"));
    System.out.println(environment.getProperty("foo.bar"));
            
}

-3
首先,您需要在属性配置文件中定义相关字段信息,然后使用@value获取和使用。 例如:
@Value("${abc}")
private String abc;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接