Чтение переменной среды в SpringBoot

Каков наилучший способ чтения переменных среды в SpringBoot?
В Java я сделал это используя:

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

Можно ли сделать это с помощью @Value аннотаций?

9 ответов

Решение

Цитирование документации:

Spring Boot позволяет вам вывести свою конфигурацию наружу, чтобы вы могли работать с одним и тем же кодом приложения в разных средах. Вы можете использовать файлы свойств, YAML-файлы, переменные окружения и аргументы командной строки для внешней настройки конфигурации. Значения свойств могут быть введены непосредственно в ваши компоненты с помощью @Value аннотация, доступ к которой осуществляется через Spring Environment абстракция или привязка к структурированным объектам через @ConfigurationProperties,

Итак, поскольку загрузка Spring позволяет использовать переменные среды для конфигурации, а загрузка Spring также позволяет использовать @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
    }
}

Вы можете сделать это с помощью аннотации @Value:

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

Вы также можете использовать двоеточие, чтобы задать значение по умолчанию, если оно не найдено:

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

Вот три "замещающих" синтаксиса, которые работают для доступа к системной переменной среды с именем 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(или похожие). Если вы хотите, чтобы это работало во время модульного тестирования, есть дополнительные гоча - см. Мой ответ на вопрос Почему мое поле Spring @Autowired имеет значение null?

В качестве альтернативы вы можете использовать org.springframework.core.env.Environment интерфейс для доступа к переменным среды:

@Autowired
private Environment env;

...

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

Прочитайте больше...

Да, ты можешь. Однако в большинстве ответов не упоминается, порядок очень важен, пожалуйста, проверьте это https://docs.spring.io/spring-boot/docs/1.5.6.RELEASE/reference/html/boot-features-external-config.html

Ваш OS environment variables перезапишет значение, полученное из Application properties packaged inside your jar (application.properties and YAML variants)., поэтому в основном переменные среды имеют более высокий приоритет.

Вы можете поместить переменную среды в файл 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;

}
    

В редких случаях, если вы хотите получить доступ к параметрам среды весной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"));
            
}

вы можете использовать его с аннотацией @Value для классов @Components и @service. Иногда это не сработает, если это обычный класс.

Пример:

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

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

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

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

Во-первых, вы должны определить соответствующую информацию о поле в файле конфигурации свойств, а затем использовать значение @ для получения и использования примера:

      @Value("${abc}")
private String abc;
Другие вопросы по тегам