Spring Boot: настройка свойств

Введение В этой статье мы углубимся в настройку свойств загрузки Spring. Spring позволяет разработчикам настраивать огромное количество свойств для своих проектов. Spring Boot, помимо того, что позволяет разработчикам начать работу над проектом с нуля, намного проще и удобнее, чем Spring, также значительно упрощает настройку свойств для ваших приложений. Существует несколько способов настройки проекта Spring: * на основе Java * на основе XML * на основе свойств Java и XML-bas

Вступление

В этой статье мы погрузимся в настройку свойств загрузки Spring .

Spring позволяет разработчикам настраивать огромное количество свойств для своих проектов. Spring Boot, помимо того, что позволяет разработчикам начать работу над проектом с нуля, намного проще и удобнее, чем Spring, также значительно упрощает настройку свойств для ваших приложений.

Есть несколько способов настроить проект Spring:

  • На основе Java
  • На основе XML
  • На основе свойств

Конфигурация свойств на основе Java и XML была классическим способом настройки приложений Spring до того, как Spring Boot представил нам файл application.properties

Это дополнение позволяет нам настраивать приложение извне и легко получать доступ к свойствам, определенным в файле.

По умолчанию application.properties можно использовать для хранения пар свойств, хотя вы также можете определить любое количество дополнительных файлов свойств.

Чтобы зарегистрировать файл свойств, вы можете аннотировать @Configuration с помощью дополнительной аннотации @PropertySource

 @Configuration 
 @PropertySource("classpath:custom.properties") 
 public class ConfigClass { 
 // Configuration 
 } 

Используя этот метод, вы можете зарегистрировать любое количество дополнительных файлов .properties

 @Configuration 
 @PropertySource("classpath:custom.properties") 
 @PropertySource("classpath:another.properties") 
 public class ConfigClass { 
 // Configuration 
 } 

Внедрение свойств загрузки Spring

Настройка приложения

Самый простой способ начать работу со скелетным проектом - использовать Spring Initializr . Выберите предпочитаемую версию Spring Boot, добавьте Web зависимость и сгенерируйте ее как проект Maven:

SpringInitializr{.ezlazyload}

Если вы откроете проект, вы заметите, что файл application.properties хранится по пути src/main/resources .

Это файл по умолчанию, который Spring использует для загрузки свойств. Здесь мы можем записать наши пользовательские или специфичные для Spring свойства в виде пар ключ-значение:

 message.default.welcome=Welcome... 
 message.default.goodbye=Goodbye... 

Вместо properties мы также можем использовать .yml и определить те же свойства, что и:

 message: 
 default: 
 welcome: Welcome... 
 goodbye: Goodbye... 

Это работает из-за jar-файла SnakeYaml, присутствующего в пути к классам. Файлы YAML более краткие и поддерживают карты, списки и т. Д.

Какой тип использовать - решать вам и вашей команде. В этом руководстве мы будем использовать .properties

Внедрение свойств с использованием @Value

Давайте посмотрим, как мы можем использовать эти свойства в простом REST API:

 @RestController 
 public class GreetController { 
 
 @Value("${message.default.welcome}") 
 private String welcomeMessage; 
 
 @Value("${message.default.goodbye}") 
 private String goodBye; 
 
 @RequestMapping("/welcome") 
 public String welcome() { 
 return welcomeMessage; 
 } 
 
 @RequestMapping("/bye") 
 public String bye() { 
 return goodBye; 
 } 
 } 

Это довольно просто. Используя @Value , мы можем application.properties в поля класса в управляемом Spring bean-компоненте GreetController .

Затем у нас есть пара конечных точек REST, которые просто возвращают эти значения:

Результат{.ezlazyload}

Использование @Value позволяет вам установить значение по умолчанию, если запрошенное по какой-либо причине недоступно:

 @Value("${message.default.welcome:SomeDefaultValue}") 
 private String welcomeMessage; 

Если message.default.welcome отсутствует, будет установлено значение SomeDefaultValue .

Если вы хотите узнать больше об аннотации @Value , у нас есть подробная статья об этом!

Внедрение свойств с помощью @ConfigurationProperties

Если у наших свойств есть какой-то общий контекст, такой как один и тот же префикс, мы можем использовать @ConfigurationProperties которая сопоставит эти свойства с объектами Java:

 @Configuration 
 @ConfigurationProperties(prefix = "message.default") 
 public class MessageProperties { 
 
 private String welcome; 
 private String goodbye; 
 
 // Getters and Setters 
 } 
  • @Configuration скажет Spring создать bean-компонент этого класса.
  • @ConfigurationProperties инициализирует поля соответствующими именами свойств.

Теперь мы можем использовать этот bean-компонент в других bean-компонентах, управляемых Spring:

 @Autowired 
 MessageProperties messageProperties; 

Переопределение свойств

Естественно, что по мере расширения и изменения среды нашего приложения (разработка, контроль качества, производство и т. Д.) Некоторые из наших свойств также изменятся. Они могут мешать друг другу, если мы не разделяем их каким-либо образом.

Мы достигаем этого, поддерживая разные файлы или получая значения свойств через переменные среды.

Использование профилей Spring

Самый распространенный способ записать «изменяющиеся» свойства - сохранить их в разных файлах. Эти файлы зависят от среды, и наше приложение может загружать их на основе переменных среды.

Spring Boot предоставляет очень элегантный способ справиться с этим.

Все, что нам нужно сделать, это следовать соглашению об именах - application-<environment>.properties для наших файлов свойств:

  • application-dev.properties
  • application-qa.properties
  • application-production.properties и т. д.

Чтобы сообщить Spring, какие файлы использовать, мы должны установить переменную среды - spring.profiles.active .

При этом, если значение spring.profiles.active равно dev , например, загрузка Spring загрузит application-dev.properties и тому подобное.

Примечание . application.properties загружается всегда, независимо от значения spring.profiles.active Если один и тот же ключ-значение присутствует как в application.properties и в application-<environment>.properties , последнее переопределит первое.

Обычно мы записываем все общие свойства каждой среды в application.properties и переопределяем специфичные для среды свойства с помощью зависящего от профиля application-<environment>.properties .

Давайте посмотрим на это, создав application-dev.properties :

 message.default.welcome = Welcome to DEV environment... 

Есть несколько способов настроить переменную spring.profiles.active

Если мы запускаем приложение через Eclipse, мы можем установить это в аргументах виртуальной машины:

Аргументы виртуальной машиныEclipse{.ezlazyload}

Мы можем установить его в переменных окружения ОС, как в Windows:

окнаenv{.ezlazyload}

Давайте запустим наше приложение и в журналах вы увидите загружаемый профиль dev

весенние профили активные журналыразработчиков{.ezlazyload}

Давайте проверим обе наши предыдущие конечные точки REST:

пружинные профили activedev{.ezlazyload}

Как мы видим, значение message.default.welcome из файла application-dev.properties а свойство message.default.goodbye application.properties .

У нас может быть несколько значений в spring.profiles.active например dev,qa :

пружинные профили active dev /qa{.ezlazyload}

Любой повторяющийся ключ будет переопределен последним профилем, в приведенном выше случае qa .

Мы также можем передать spring.profiles.active в качестве аргумента командной строки, например:

 java -jar -Dspring.profiles.active=dev greeting-service-0.0.1-SNAPSHOT.jar 

Создание application.properties из местоположения сборки

Мы также можем переопределить внутренние свойства, создав application.properties на том же уровне, на котором выполняется .jar . Контекст Spring переопределит свойства, используя этот только что созданный файл.

Это отличный способ распространения вашего приложения среди других, которые могут переопределить определенные свойства в зависимости от своей среды, например, конфигурации базы данных.

Есть и другие способы экстернализации ваших свойств, таких как переменные среды ОС, аргументы командной строки и т. Д. Порядок, в котором Spring считает это, можно найти здесь .

Внешний перенос свойств с помощью сервера облачной конфигурации

Многие из создаваемых в настоящее время приложений полагаются на микросервисную архитектуру. Эти приложения не только развертываются отдельно, но и могут иметь несколько экземпляров самих себя (в зависимости от нагрузки), а общее количество может легко превысить 100.

Управление недвижимостью в этом архитектурном стиле обычными методами требует слишком больших усилий. Кроме того, чтобы изменить свойство, мы должны заново собрать приложение и развернуть его или, в лучшем случае, перезапустить приложение. Это требует простоя, который сводит на нет всю цель микросервисов.

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

Spring Cloud Config предоставляет централизованный, внешний, безопасный и простой способ хранения и обслуживания конфигураций приложений для различных сред:

схема сервера конфигурацииSpring{.ezlazyload}

Короче говоря, у нас есть сервер конфигурации, работающий как отдельное приложение, которое подключается к репозиторию Git.

Когда мы запускаем новое приложение (клиент конфигурации), оно получает все необходимые свойства с сервера конфигурации. Когда мы настраивали сервер, не имеет значения, существовало приложение или нет.

Создание сервера конфигурации

Как всегда, мы начинаем с использования Spring Initializr .

Выберите предпочитаемую версию Spring Boot, добавьте зависимость Config Server и сгенерируйте ее как проект Maven:

сервер конфигурацииSpring{.ezlazyload}

@EnableConfigServer наш основной класс с помощью @EnableConfigServer, мы отмечаем его как конфигурационный сервер:

 @SpringBootApplication 
 @EnableConfigServer 
 public class Application { 
 
 public static void main(String[] args) { 
 SpringApplication.run(Application.class, args); 
 } 
 } 

А теперь нам нужно настроить несколько вещей в файле application.properties

 server.port = 8888 
 spring.cloud.config.server.git.uri = https://github.com/dhananjay12/spring-cloud-config 
 spring.cloud.config.server.git.searchPaths = app-properties 

Здесь мы определили порт, на котором будет работать сервер конфигурации. Затем мы указали URL-адрес Git, который нужно перехватить для свойств.

Примечание . По умолчанию Spring ищет файлы свойств в корне. Если нам нужно указать конкретную папку, мы можем указать ее местоположение через searchPaths .

Вот как выглядит репозиторий Git:

облако службыприветствия{.ezlazyload}

Теперь мы можем запустить сервер конфигурации. Если вы хотите проверить конфигурацию Spring Config Server, следуя соглашению, http://localhost:8888/<application-name>/<spring-profiles> покажет нам всю необходимую информацию.

В нашем случае это будет - http: // localhost: 8888 / welcome-service-cloud / default :

облако службыприветствия{.ezlazyload}

Создание клиента конфигурации

Давайте создадим ту же службу приветствия, но с парой дополнительных зависимостей:

облако службыприветствия{.ezlazyload}

Здесь мы создали greeting-service-cloud сервис приветствия с зависимостями Web , Config Client и Actuator

Он имеет те же сопоставления REST, что и раньше, с добавлением аннотации @RefreshScope Эта аннотация позволяет компоненту динамически обновляться во время выполнения:

 @RestController 
 @RefreshScope 
 public class GreetController { 
 
 @Value("${message.default.welcome}") 
 private String welcomeMessage; 
 
 @Value("${message.default.goodbye}") 
 private String goodBye; 
 
 @RequestMapping("/welcome") 
 public String welcome() { 
 return welcomeMessage; 
 } 
 @RequestMapping("/bye") 
 public String bye() { 
 return goodBye; 
 } 
 } 

Теперь помимо application.properties нам нужно создать bootstrap.properties , который загружается перед application.properties .

Обычно он используется Spring Config Client для получения свойств с Spring Config Server :

 spring.application.name = greeting-service-cloud 
 spring.cloud.config.uri = http://localhost:8888 

Здесь мы сначала устанавливаем имя приложения. Сервер Spring Config будет искать это имя файла в репозитории Git и обслуживать его содержимое.

Мы также должны указать, где работает Config Server, указав его в spring.cloud.config.uri .

Запустим этот сервис и посмотрим логи:

облачные журналы службыприветствия{.ezlazyload}

Обратите внимание, что он сначала получил свойства от Spring Config Server.

Примечание . Если сервер конфигурации недоступен, приложение не запустится.

Теперь давайте проверим наши конечные точки REST:

API облачной службыприветствия{.ezlazyload}

Таким образом, мы реализовали наши свойства во внешнем виде и получили возможность отслеживать их в нашем репозитории Git. Стоит отметить несколько важных моментов:

  • Здесь мы также можем использовать spring-profiles-active . Если эта переменная установлена в среде Config Client, например. dev , он будет передан на сервер конфигурации при запросе свойств. Затем сервер конфигурации будет искать greeting-service-cloud-dev.properties -service-cloud-dev.properties в репозитории Git и передавать его клиенту.
  • Если application.properties , он будет обслуживаться всем клиентам в дополнение к другим файлам.
  • Если клиент конфигурации запрашивает свойства, например, например, dev , сервер конфигурации вернет application.properties , application-dev.properties и greeting-service-cloud-dev.properties . Общие свойства будут отменены последним.

Обновление свойств без перезапуска

По умолчанию значения конфигурации из файлов свойств готовы или извлекаются при запуске приложения, а не повторно. Если необходимо внести какие-то изменения, нам все равно придется перезапустить приложение.

Чтобы решить эту проблему, мы добавили в наше приложение зависимость Actuator. Он предоставляет несколько готовых к работе конечных точек, которые могут дать представление о нашем приложении, которое можно использовать в административных целях.

Мы должны включить эти конечные точки вручную, указав management.endpoints.web.exposure.include = * в свойствах приложения.

Давайте добавим это в репозиторий Git и перезапустим приложение. Мы можем проверить многие детали нашего приложения, посетив конечные точки, такие как http: // localhost: 8080 / actator / env , http: // localhost: 8080 / actator / mappings и т. Д.

Нас интересует /actuator/refresh . Мы можем заставить bean-компонент обновить свою конфигурацию (т.е. снова получить конфигурацию с сервера конфигурации), аннотируя bean-компонент с помощью @RefreshScope .

Примечание . Если компонент обновляется, то при следующем обращении к нему (т. Е. При выполнении метода) создается новый экземпляр.

Это может быть вызвано отправкой пустого HTTP- запроса POST в конечную точку обновления клиента - http://<host:port>/actuator/refresh .

Давайте изменим значение единицы в репозитории Git на другое:

 message.default.welcome = Welcome from cloud config server changed... 
 message.default.goodbye = Goodbye... 
 
 management.endpoints.web.exposure.include = * 

Теперь давайте активируем конечную точку обновления:

 curl localhost:8080/actuator/refresh -d {} -H "Content-Type: application/json" 

Проверьте конечную точку /welcome

обновление облака службыприветствия{.ezlazyload}

Итак, мы смогли обновить свойство работающего приложения без его перезапуска.

Заключение

В этой статье мы рассмотрели, как настроить свойства в нашем приложении Spring Boot.

Во-первых, мы обсудили простые способы добавления свойств в наше приложение, а затем изменения / переопределения этих свойств в зависимости от различных сред.

Во-вторых, мы рассмотрели, как получить свойства из Spring Config Server и как обновить свойства без перестройки или перезапуска.

Как всегда, код примеров, использованных в этой статье, можно найти на Github .

comments powered by Disqus