Spring Boot містить додатковий набір інструментальних засобів, які можуть зробити процес розробки додатків трохи
приємнішим. Модуль spring-boot-devtools
можна додавати до будь-якого проєкту для забезпечення
додаткових функцій під час розробки. Щоб впровадити підтримку інструментальних засобів розробки (devtools), додай
залежність модуля до свого складання, як показано в наступних лістингах для Maven та Gradle:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
dependencies {
developmentOnly("org.springframework.boot:spring- boot-devtools")
}
java-jar
або через спеціальний
завантажувач класів, вона вважається "виробничим додатком". Ти можеш керувати цією логікою роботи за допомогою
системної властивості spring.devtools.restart.enabled
. Щоб активувати devtools, незалежно від
завантажувача
класів, який використовується для запуску програми, встанови системну властивість -Dspring.devtools.restart.enabled=true
.
Цього не можна робити у виробничому середовищі, де виконання devtools становить загрозу безпеці. Щоб відключити
devtools, вимкни залежність або встанови системну властивість
-Dspring.devtools.restart.enabled=false
.
developmentOnly
у Gradle (як показано вище), це запобігатиме транзитному застосуванню
devtools до інших модулів, що використовують твій проєкт.
excludeDevtools
значення false
.
При використанні плагіна для Gradle конфігуруй classpath для завдання так, щоб він містив конфігурацію developmentOnly
.
Діагностика проблем із завантаженням класів
Функціональність перезапуску реалізована за допомогою двох завантажувачів класів. Для більшості програм такий підхід працює добре. Однак іноді він може призвести до проблем із завантаженням класів, особливо в багатомодульних проєктах.
Щоб діагностувати, чи справді проблеми із завантаженням класів викликані devtools та їх двома завантажувачами класів, спробуй вимкнути перезапуск. Якщо це вирішить проблеми, налаштуй перезапуск завантажувача класів на охоплення всього проєкту.
Властивості за замовчуванням
Деякі бібліотеки, що підтримуються Spring Boot, використовують кеші для підвищення продуктивності. Наприклад, шаблонізатори кешують скомпільовані шаблони, щоб уникнути повторного парсингу файлів шаблонів. До того ж, Spring MVC може додавати заголовки HTTP-кешування у відповіді при обробці статичних ресурсів. Хоча кешування дуже корисне у виробничому середовищі, воно може бути контрпродуктивним під час розробки, не дозволяючи бачити зміни, які були тільки що внесені до додатку. Тому spring-boot-devtools за замовчуванням деактивує налаштування кешування.
Налаштування кешу зазвичай конфігуруються за допомогою параметрів у файлі
application.properties
. Наприклад, Thymeleaf передбачає властивість spring.thymeleaf.cache
.
Замість того, щоб встановлювати ці властивості вручну, модуль spring-boot-devtools
автоматично
застосовує адекватну конфігурацію на час розробки.
У наступній таблиці перераховані всі властивості:
Ім'я | Значення за замовчуванням |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
spring.devtools.add-properties
у false
у файлі application.properties
.
Оскільки при розробці додатків на Spring MVC і Spring WebFlux потрібно більше інформації про вебзапити,
інструментальні засоби розробки передбачають активацію DEBUG
журналювання для web
-групи
журналювання. Це дасть інформацію про вхідний запит, який обробник його обробляє, про результат відповіді та інші
подробиці. Якщо потрібно реєструвати всі відомості запиту (включно з потенційною конфіденційною інформацією), можна
включити властивості конфігурації spring.mvc.log-request-details
або spring.codec.log-request-details
.
Автоматичний перезапуск
Програми, що використовують spring-boot-devtools
, автоматично
перезапускаються при зміні файлів у classpath. Це може бути корисною функцією при роботі в IDE, оскільки забезпечує
дуже швидкий зворотний зв'язок для внесення змін до коду. За замовчуванням будь-який запис у classpath, що вказує на
каталог, відстежується щодо змін. Зверни увагу, що деякі ресурси, такі як статичний вміст та шаблони подання, не
вимагають перезапуску програми.
forking
, встановлене в enabled
. Якщо ти
відключиш розгалуження (форкінг), ізольований завантажувач класів програми, що використовується devtools, не буде
створено, а перезавантаження не буде працювати належним чином.
SpringApplication.setRegisterShutdownHook(false)
).
ResourceLoader
, який
використовується ApplicationContext
. Якщо твій додаток вже передбачає такий завантажувач, він буде
обернутий. Пряме перевизначення методу
getResource
на ApplicationContext
не підтримується.
Технологія перезапуску, передбачена Spring Boot, працює за допомогою двох завантажувачів класів. Класи, які не змінюються (наприклад, класи зі сторонніх jar-файлів), завантажуються до основного завантажувача класів. Класи, які активно розробляються, завантажуються до завантажувача класів, що перезапускає. Якщо програма перезапускається, перезапускаючий завантажувач класів одночасно використовується, після чого створюється новий. Такий підхід означає, що перезапуск програми зазвичай відбувається набагато швидше, ніж "холодний запуск", оскільки основний завантажувач класів вже доступний і заповнений.
Якщо ти виявиш, що перезавантаження недостатньо швидке для твоїх програм або ти стикаєшся з проблемами завантаження класів, можна ознайомитися з технологіями перезавантаження, такими як JRebel від ZeroTurnaround. Вони працюють шляхом переписування класів у міру їх завантаження, щоб вони були зручнішими для повторного завантаження. За замовчуванням при кожному перезапуску програми до журналу заноситься звіт, що показує дельту обчислення стану. Звіт демонструє зміни в автоконфігурації вашої програми в міру того, як ти вносиш зміни, такі як додавання або видалення бінів і встановлення властивостей конфігурації. Щоб вимкнути журналювання з формуванням звіту, встанови таку властивість:
spring.devtools.restart.log-condition-evaluation-delta=false
spring: devtools: restart: log-condition-evaluation-delta: false
Вилучення ресурсів
Деякі ресурси не обов'язково повинні ініціювати перезавантаження при їх зміні. Наприклад, шаблони Thymeleaf можна
редагувати на тому ж місці. За замовчуванням зміна ресурсів у /META-INF/maven
, /META-INF/resources
,
/resources
, /static
, /public
або /templates
не ініціює
перезапуск, але ініціює перезавантаження в реальному часі. Якщо ти бажаєш налаштувати ці винятки, можна
використовувати властивість spring.devtools.restart.exclude
. Наприклад, щоб вимкнути лише
/static
та /public
, потрібно встановити таку властивість:
spring.devtools.restart.exclude=static/**,public/**
spring: devtools: restart: exclude: "static/**,public/**"
spring.devtools.restart.additional-exclude
.
Відстеження додаткових шляхів
Тобі може знадобитися, щоб програма перезапускалася або перезавантажувалася після внесення змін до файлів, яких
немає в classpath. Для цього використовуй властивість spring.devtools.restart.additional-paths
,
щоб налаштувати додаткові шляхи для відстеження змін. Ти можеш використовувати властивість spring.devtools.restart.exclude
,
щоб керувати тим, чи будуть зміни в додаткових шляхах ініціювати повний перезапуск або перезавантаження в
реальному часі.
Вимкнення перезапуску
Якщо тобі не потрібно використовувати функцію перезапуску, можна вимкнути її за допомогою властивості spring.devtools.restart.enabled
.
У більшості випадків можна встановити цю властивість у файлі application.properties
(так все одно
ініціалізуватиметься перезапускаючий завантажувач класів, але зміни файлів не будуть відстежуватися).
Якщо потрібно повністю вимкнути засоби підтримки перезапуску (наприклад, через те, що вони не
працюють з певною бібліотекою), то перед викликом SpringApplication.run(…)
потрібно встановити
властивість System
для spring.devtools.restart.enabled
у false
, як це
показано в наступному прикладі:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
System.setProperty("spring.devtools.restart.enabled", "false");
SpringApplication.run(MyApplication.class, args);
}
}
import org.springframework.boot.SpringApplication
import org.springframework.boot.autoconfigure.SpringBootApplication
@SpringBootApplication
object MyApplication {
@JvmStatic
fun main(args: Array<String>) {
System.setProperty("spring.devtools.restart.enabled", "false")
SpringApplication.run(MyApplication::class.java, *args)
}
}
Використання тригерного файлу
Якщо ти працюєш з IDE, яка постійно компілює файли, що змінюються, то можна віддати перевагу ініціації перезавантаження тільки в певні моменти. Для цього ти можеш використовувати "тригерний файл", що є спеціалізованим файлом, який необхідно змінити, якщо ти дійсно хочеш ініціювати перевірку перезапуску.
Наприклад, якщо у тебе є проєкт із наступною структурою:
src +- main +- resources +- .reloadtrigger
Тоді властивість вашого trigger-file
буде таким:
spring.devtools.restart.trigger-file=.reloadtrigger
spring:
devtools:
restart:
trigger-file: ".reloadtrigger "
Перезапуск буде відбуватися тільки під час оновлення src/main/resources/.reloadtrigger
.
spring.devtools.restart.trigger-file
як глобальний параметр, щоб усі твої проєкти мали однакову логіку роботи.
У деяких IDE існують функції, які позбавляють необхідності оновлювати тригерний файл вручну. Spring Tools для Eclipse та IntelliJ IDEA (Ultimate Edition) мають такі
засоби отримання. У Spring Tools ти можеш використовувати кнопку "reload" з подання консолі (за умови, що
твій trigger-file
має ім'я .reloadtrigger
). У випадку з IntelliJ IDEA можна
дотримуватися інструкцій у відповідній документації..
Налаштування завантажувача класів, що перезапускає
Функціональність перезапуску реалізована через два завантажувача класів. Якщо виникають якісь проблеми, тобі може знадобитися налаштувати, що і яким завантажувачем класів завантажуватиметься.
За замовчуванням будь-який відкритий проєкт в IDE завантажується із завантажувачем класів, що
перезапускає, а будь-який звичайний .jar
-файл завантажується з "основним" завантажувачем
класів. Те ж саме, якщо використовується mvn spring-boot:run
або gradle bootRun
:
проєкт, що містить анотацію @SpringBootApplication
, завантажується з "перезапускаючим"
завантажувачем класу, а все інше — з "основним" завантажувачем класів.
Можна дати Spring Boot команду завантажувати компоненти проєкту з іншим завантажувачем класів, створивши файл
META-INF/spring-devtools.properties
. Файл spring-devtools.properties
може містити
властивості з префіксами restart.exclude
та restart.include
. Елементи
include
— це компоненти, які потрібно підняти вгору в "завантажувач класів, що перезапускає", а елементи
exclude
— це елементи, які потрібно опустити вниз в "основний" завантажувач класів. Значення властивості є шаблоном
регулярних виразів, який застосовується до classpath, як показано в наступному прикладі:
restart.exclude.companycommonlibs=/mycorp-common-[\\w\\d-\\.]+\\.jar
restart.include.projectcommon=/mycorp-myproj-[\\w\\d-\\.]+\ \.jar
restart:
exclude:
companycommonlibs: "/mycorp-common-[\\w\\d-\\.]+\\.jar"
include:
projectcommon: "/mycorp-myproj-[\\w\\d-\\.]+\\.jar "
restart.include.
або restart.exclude.
, вона враховується.
META-INF/spring-devtools.properties
з
classpath. Ти можеш упаковувати файли всередині свого проєкту або в бібліотеках, які використовує проєкт.
Відомі обмеження
Функціональність перезапуску не дуже добре працює з об'єктами, які десеріалізуються за допомогою стандартного ObjectInputStream
.
Якщо
необхідно десеріалізувати дані, то може знадобитися використовувати ConfigurableObjectInputStream
зі Spring у поєднанні з Thread.currentThread().getContextClassLoader()
.
На жаль, деякі сторонні бібліотеки десеріалізують без урахування контекстного завантажувача класів. Якщо ти зіткнешся з такою проблемою, необхідно буде зробити запит на виправлення до авторів-творців.
LiveReload
Модуль spring-boot-devtools
містить вбудований сервер LiveReload, який можна використовувати
для ініціації оновлення браузера під час зміни ресурсу. Розширення для браузера LiveReload для Chrome,
Firefox та Safari знаходяться у вільному доступі на сайті livereload.com.
Якщо запускати сервер LiveReload під час виконання програми не потрібно, то можна встановити властивість
spring.devtools.livereload.enabled
у false
.
Глобальні параметри
Ти можеш налаштувати глобальні параметри devtools, додавши будь-який з наступних файлів до каталогу
$HOME/.config/spring-boot
:
spring-boot-devtools.properties
spring-boot-devtools.yaml
spring-boot-devtools.yml
Будь-які властивості, додані в ці файли застосовуються до усіх програм Spring Boot у твоїй
машині, які використовують devtools. Наприклад, щоб налаштувати перезапуск на постійне використання
тригерного файлу, потрібно додати таку властивість до файлу spring-boot-devtools
:
spring.devtools.restart.trigger-file=.reloadtrigger
spring:
devtools:
restart:
trigger-file: ".reloadtrigger"
За замовчуванням $HOME
— це початковий каталог користувача. Щоб налаштувати це місце,
встанови змінну оточення SPRING_DEVTOOLS_HOME
або системну властивість
spring.devtools.home
.
$HOME/.config/spring-boot
,
в корені каталогу $HOME
буде здійснено пошук на предмет наявності файлу .
spring-boot-devtools.properties
. Це дозволить спільно використовувати глобальну конфігурацію devtools
з додатками, які працюють на більш старій версії Spring Boot, яка не підтримує розташування $HOME/.config/spring-boot
.
Профілі не підтримуються у файлах properties/yaml для devtools.
Будь-які профілі активовані в .spring-boot-devtools.properties
, не впливатимуть на
завантаження пов'язаних із конкретним профілем файлів. Імена файлів, специфічні для профілів (виду
spring-boot-devtools-<profile>.properties
), та документи spring.config.activate.on-profile
у файлах YAML і Properties не підтримуються.
Конфігурування watcher-а файлової системи
FileSystemWatcher працює шляхом опитування змін класу в певних інтервалах часу, а
потім чекає на певний період бездіяльності, щоб переконатися, що змін більше немає. Оскільки Spring Boot
повністю покладається на IDE при компіляції та копіюванні файлів у місце, звідки Spring Boot може їх
прочитати, ти можеш зіткнутися з тим, що деякі зміни не будуть відображені при перезапуску програми за
допомогою devtools. Якщо вти спостерігаєш подібні проблеми постійно, спробуйте збільшити параметри spring.devtools.restart.poll-interval
та spring.devtools.restart.quiet-period
до значень, які відповідають твоєму оточенню розробки:
spring.devtools.restart.poll-interval=2s
spring.devtools.restart.quiet-period= 1s
spring:
devtools:
restart:
poll-interval : "2s"
quiet-period: "1s"
Тепер відстежувані каталоги classpath опитуються кожні 2 секунди на предмет змін, а 1-секундний період бездіяльності дотримується, щоб переконатися у відсутності додаткових змін класів.
Віддалені програми
Інструменти розробника Spring Boot не обмежуються локальною розробкою. Ти також можеш використовувати кілька функцій під час віддаленого запуску програм. Засоби підтримки дистанційної роботи приймаються за бажанням, оскільки їх активація може становити загрозу безпеці. Їх слід активувати лише при роботі в довіреній мережі або за наявності захисту за допомогою SSL. Якщо жоден з цих варіантів недоступний, не слід використовувати засоби підтримки дистанційної роботи для DevTools. У жодному разі не слід активувати засоби підтримки при виробничому розгортанні.
Щоб активувати підтримку, необхідно переконатися, що devtools
міститься в переупакованому
архіві, як показано в наступному лістингу:
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludeDevtools>false</excludeDevtools>
</configuration>
</plugin>
</plugins>
</build>
Тому необхідно встановити властивість spring.devtools.remote.secret
. Як і будь-який важливий
пароль або конфіденційні відомості, значення має бути унікальним і надійним, щоб його не можна було вгадати
або підібрати методом перебору.
Засоби підтримки віддаленої роботи для devtools надаються в двох частинах: кінцева точка на стороні сервера,
приймаюча з'єднання, і клієнтська програма, яку ти виконуєш у своїй IDE.
Серверний компонент автоматично активується, якщо встановлено властивість
spring.devtools.remote.secret
.
Клієнтський компонент потрібно запускати вручну.
Виконання віддаленої клієнтської програми
Віддалена клієнтська програма розроблена для виконання з
твоєї IDE. Необхідно виконати org.springframework.boot.devtools.RemoteSpringApplication
з тим
же classpath, що й віддалений проєкт, до якого ти підключаєшся. Єдиним обов'язковим аргументом програми є
віддалена URL-адреса, до якої вона підключається.
Наприклад, якщо використовується Eclipse або Spring Tools і є проєкт з ім'ям my-app
, який
розгорнути в Cloud Foundry, потрібно зробити таке:
Вибрати
Run Configurations…
з менюRun
.Створити нову "конфігурацію запуску"
Java Application
.Знайти проєкт
my-app
.Використовувати
org.springframework.boot.devtools.RemoteSpringApplication
як основний клас.Додати
https://myapp.cfapps.io
уProgram arguments
(або будь-яка інша URL-адреса вашого віддаленого доступу).
Віддалений клієнт, що виконується, може виглядати так:
. ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ ___ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | | _ \___ _ __ ___| |_ ___ \ \ \ \ \\/ ___)| |_)| | | | | || (_| []::::::[] / -_) ' \/ _ \ _/ -_) ) ) ) ) ' |____| .__|_| |_|_| |_\__, | |_|_\___|_|_|_\___/\__\___|/ / / / =========|_|==============|___/===================================/_/_/_/ :: Spring Boot Remote :: (v2.7.5) 2022-10-20 12:40:15.175 INFO 16215 --- [ main] o.s.b.devtools.RemoteSpringApplication : Starting RemoteSpringApplication v2.7.5 using Java 1.8.0_345 on myhost with PID 16215 (/Users/myuser/.m2/repository/org/springframework/boot/spring-boot-devtools/2.7.5/spring-boot-devtools-2.7.5.jar started by myuser in /opt/apps/) 2022-10-20 12:40:15.182 INFO 16215 --- [ main] o.s.b.devtools.RemoteSpringApplication : Немає активного set, falling back to 1 default profile: "default" 2022-10-20 12:40:15.913 INFO 16215 --- [ main] o.s.b.d.a.OptionalLiveReloadServer : LiveReload server є керування на port 35729 2022-10-20 12:40:15.946 INFO 16215 --- [ main] o.s.b.devtools.RemoteSpringApplication : Started RemoteSpring2
spring.devtools.remote.secret
і передається серверу для аутентифікації.
https ://
в якості
протоколу підключення, щоб трафік був зашифрований і паролі не можна було перехопити. Якщо необхідно використати
проксі для доступу до віддаленого застосунку, налаштуй
властивості spring.devtools.remote.proxy.host
та spring.devtools.remote.proxy.port
.
Видалене оновлення
Віддалений клієнт відстежує зміни в шляху класів твоєї програми так само, як це робить програма локального перезапуску. Будь-який оновлений ресурс передається віддаленому додатку і (якщо потрібно) ініціює перезапуск. Це може бути корисним, якщо ти повторюєш функцію, яка використовує хмарну службу, якої немає на локальному рівні. Зазвичай віддалене оновлення та перезавантаження відбуваються набагато швидше, ніж повна перебудова та розгортання.
В оточенні з повільною розробкою може статися так, що періоду бездіяльності буде недостатньо, а зміни в класах можуть бути розбиті на пакети. Сервер перезапускатиметься після завантаження першого пакета змін класу. Наступний пакет не можна буде відправити до програми, оскільки сервер перезапускається.
Зазвичай це проявляється у вигляді попередження в журналах RemoteSpringApplication
про те, що не
вдалося завантажити деякі класи, і подальшої повторної спроби. Але це також може вилитися в неузгодженість
коду програми та неможливість перезапуску після завантаження першого пакета змін. Якщо ти спостерігаєш
подібні проблеми постійно, спробуй збільшити параметри spring.devtools.restart.poll-interval
та spring.devtools.restart.quiet-period
до значень, які відповідають вашому оточенню розробки.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ