Spring devtools что это
Spring Blog
DevTools in Spring Boot 1.3
To use the module you simply need to add it as a dependency in your Maven POM:
or your Gradle build file:
Once included, the spring-boot-devtools module provides a number of nice features that we cover below (If you can’t be bother to read the text, skip to the end of the post for a short video).
Property Defaults
Now, when you use the spring-boot-devtools module, you no longer need to remember to set the properties. During development caching for Thymeleaf, Freemarker, Groovy Templates, Velocity and Mustache are all automatically disabled.
Automatic Restart
You may have used tools such as JRebel or Spring Loaded in the past to provide instant reload for your Java applications. These tools are great, but they do often require additional configuration or IDE plugins to work (and some of them even cost money!)
With Spring Boot 1.3 we’ve been working on something that’s a little slower than these “instant reload” techniques, and instead works by restarting your application. When you have the spring-boot-devtools module included, any classpath file changes will automatically trigger an application restart. We do some tricks to try and keep restarts fast, so for many microservice style applications this technique might be good enough.
LiveReload
With sensible “cache properties” and “automatic restarts” working, needing to manually click the browser refresh button each time something changes starts to become a little tedious. So to help save your mouse buttons, Spring Boot 1.3 DevTools includes an embedded LiveReload server. LiveReload is a simple protocol that allows your application to automatically trigger a browser refresh whenever things change. Browser extensions are freely available for Chrome, Firefox and Safari from livereload.com.
Remote Debug Tunneling
To help with this, Spring Boot 1.3 can tunnel JDWP (the Java Debug Wire Protocol) over HTTP directly to your application. This can even work with applications deployed to Internet Cloud providers that only expose port 80 and 443 (although since JDWP is quite a chatty protocol this can be quite slow).
Remote Update and Restart
The final trick that DevTools offers is support for remote application updates and restarts. This works by monitoring your local classpath for file changes and pushing them to a remote server which is then restarted. As with local restarts, you can also use this feature in combination with LiveReload.
Video Preview
All the features discussed in this post are already available in Spring Boot 1.3.0.M1 and detailed documentation is available in the reference guide. If you’re not ready to install the bits yourself yet, here’s a short video that shows how they work:
Как писать на Spring в 2017
В одной из классических статей для новичков, мелькавших недавно на Хабре, рассказывалось про создание базового Web приложения на Java. Все начиналось с сервлета, потом создания JSP страницы и, наконец, деплоймента в контейнер. Посмотрев на это свежим взглядом я понял, что для как раз для новичков это, наверняка, выглядит совершенно жутко — на фоне простых и понятных PHP или Node.js, где все просто — написал контроллер, вернул объект, он стал JSON или HTML. Чтобы немного развеять это ощущение, я решил написать «Гайд для новичков в Spring». Цель это статьи — показать, что создание Web приложений на Java, более того — на Spring Framework это не боль и мучительное продирание через web.xml, persistence.xml, beans.xml, и собирание приложения как карточного домика по кусочкам, а вполне себе быстрый и комфортный процесс. Аудитория — начинающие разработчики, разработчики на других языках, ну и те, кто видел Спринг в его не самые лучше времена.
Введение
В этой статье мы посмотрим, что включает в себя современный Спринг, как настроить локальное окружение для разработки Веб приложений, и создадим простое веб-приложение, которое берет данные из БД и отдает HTML страницу и JSON. Как ни странно, большинство статей (на русском языке) для начинающих, которые я нашел в топе поиска описывают и ручное создание контекста, и запуск приложения, и конфигурацию через XML — ничего из этого в современном Спринге делать, разумеется, не обязательно.
Что такое Spring?
Для начала пара слов, что же такое Spring. В настоящее время, под термином «Spring» часто подразумевают целое семейство проектов. В большинстве своем, они развиваются и курируются компанией Pivotal и силами сообщества. Ключевые (но не все) проекты семейства Spring это:
Spring Framework (или Spring Core)
Ядро платформы, предоставляет базовые средства для создания приложений — управление компонентами (бинами, beans), внедрение зависимостей, MVC фреймворк, транзакции, базовый доступ к БД. В основном это низкоуровневые компоненты и абстракции. По сути, неявно используется всеми другими компонентами.
Spring MVC (часть Spring Framework)
Стоит упомянуть отдельно, т.к. мы будем вести речь в основном о веб-приложениях. Оперирует понятиями контроллеров, маппингов запросов, различными HTTP абстракциями и т.п. Со Spring MVC интегрированы нормальные шаблонные движки, типа Thymeleaf, Freemaker, Mustache, плюс есть сторонние интеграции с кучей других. Так что никакого ужаса типа JSP или JSF писать не нужно.
Spring Data
Доступ к данным: реляционные и нереляционные БД, KV хранилища и т.п.
Spring Cloud
Много полезного для микросервисной архитектуры — service discovery, трасировка и диагностика, балансировщики запросов, circuit breaker-ы, роутеры и т.п.
Spring Security
Авторизация и аутентификация, доступ к данным, методам и т.п. OAuth, LDAP, и куча разных провайдеров.
Типичное веб приложение скорее всего будет включать набор вроде Spring MVC, Data, Security. Ниже мы увидим, как это все работает вместе.
Особняком стоит отметить Spring Boot — это вишенка на торте (а некоторые думают, что собственно сам торт), которые позволяет избежать всего ужаса XML конфигурации. Boot позволяет быстро создать и сконфигурить (т.е. настроить зависимости между компонентами) приложение, упаковать его в исполняемый самодостаточный артефакт. Это то связующее звено, которое объединяет вместе набор компонентов в готовое приложение. Пару вещей, которые нужно знать про Spring Boot:
Настройка окружения
Для того, чтобы создать простое приложение, знать, как создать проект Maven с нуля, как настроить плагины, чтобы создать JAR, какие бывают лейауты в JAR, как настроить Surefire для запуска тестов, как установить и запустить локально Tomcat, а уж тем более, как работает DispatcherServlet — совершенно не нужно.
Современное приложение на Spring создается в два шага:
Spring Initializr позволяет «набрать» в свое приложение нужных компонентов, которые потом Spring Boot (он автоматически включен во все проекты, созданные на Initializr) соберет воедино.
В качестве среды разработки подойдет что угодно, например бесплатная IntelliJ IDEA CE прекрасно справляется — просто импортируйте созданный pom.xml (Maven) или build.gradle (Gradle) файл в IDE.
Стоит отдельно отметить компонент Spring Boot который называется DevTools. Он решает проблему цикла локальной разработки, который раньше выглядел как:
В те древние времена даже родилась поговорка, что Spring это DSL для конвертации XML конфигов в стектрейсы.
С включенными Spring Boot DevTools цикл разработки сокращается до:
DevTools будут автоматом проверять изменения в скомпилированном коде или шаблонах, и очень быстро перезапускать (hot reload) только «боевую» часть приложения (как nodemon, если вы знакомы с миром node.js). Более того, DevTools включают интеграцию с Live Reload и после установки расширения в браузере, достаточно скомпилировать проект в IDEA, чтобы он автоматом обновился в браузере.
Разработка
Окей, пора приступать к практической части. Итак, наша цель — создать веб-приложение, которое отдает welcome страницу, обращается с нее же к собственному API, получает JSON с данными из базы и выводит их в таблицу.
Новый проект
Точнее, контейнер нужен — только он предоставлен и настроен Spring Boot-ом — используя Embedded Tomcat
Контроллер
Итак, наш следующий шаг — создать контроллер и вернуть «домашнюю» страницу. Код контроллера выглядит так просто, как и ожидается:
Пара вещей, на которые стоит обратить внимание.
С Котлин это бы выглядело еще лучше и проще, но это потребует введения сразу большого количества новых понятий — язык, фреймворк. Лучше начинать с малого.
Класс, помеченный как @Controller автоматически регистрируется в MVC роутере, а используя аннотации @(Get|Post|Put|Patch)Mapping можно регистрировать разные пути.
Все файлы из каталога resources/static/ считаются статическими, там можно хранить CSS и картинки.
Шаблон
Мы используем Mustache (Handlebar) синтаксис, поэтому шаблон очень напоминает обычный HTML
После компиляции проекта (⌘/Ctrl + F9) — можно сразу идти на http://localhost:8080 и увидеть созданную страницу.
Доступ к базе
Для начала, опишем нашу предметную область. Мы будем собирать статистику посещений — каждый раз, когда кто-то заходит на главную страницу, мы будем писать это в базу. Модель выглядит до крайности примитивно:
Предвидя череду комментариев «Как же без геттеров и сеттеров» и «Где же equals / hashCode» — эти элементы упущены сознательно с целью упрощения кода. Совершенно чудовищная ошибка дизайна Java которая заставляет писать эту ерунду (геттеры и методы сравнения), это, конечно, отдельный разговор. Котлин эту проблему, кстати, решает.
Мы снова очень активно используем аннотации — в этот раз из Spring Data (точнее, JPA — это дремучая спецификация для доступа к данным). Этот класс описывает модель с двумя полями, одно из которых генерится автоматически. По этому классу будет автоматически создана модель данных (таблицы) в БД.
Теперь для этой модели пора создать репозиторий. Это еще проще, чем контроллер.
Все, репозиторий можно использовать для работы с базой — читать и писать записи. У внимательного читателя должен сработать WTF детектор — что здесь вообще происходит? Мы определяем интерфейс и внезапно он начинает работать с базой? Все так. Благодаря магии Spring Boot и Spring Data «под капотом» происходит следующее:
Чтобы использовать репозиторий в контроллере мы воспользуемся механизмом внедрения зависимостей, предоставляемый Spring Framework. Чтобы это сделать, как ни странно, нужно всего лишь объявить зависимость в нашем контроллере.
Теперь можно писать в базу в методе контроллера.
REST контроллер
Следующий шаг — это вернуть все записи из базы в JSON формате, чтобы потом их можно было читать на клиенте.
На что обратить внимание:
Теперь при запросе http://localhost:8080/api/visits (предварительно скомпилировав проект и дав DevTools обновить приложение) мы получим JSON с нужными данными.
Клиентский код
Оставим за рамками этой статьи, пример можно увидеть в исходном коде. Цель этого кода — исключительно продемонстрировать как получить JSON данные с сервера, интеграции с клиентскими фреймворками React, Angular etc намеренно оставлены вне рамок этой статьи.
Тестирование
Spring так же предоставляет мощные средства для Integration и Unit тестирования приложения. Пример кода, который проверяет контроллер:
Используя абстракции типа MockMvc можно легко тестировать внешний интерфейс приложения, в то же время имея доступ к его внутренностям. Например, можно целиком заменить компоненты приложения на моки (заглушки).
Аналогично для API тестов есть набор хелперов для проверки JsonPath выражений.
Тестирование в Spring это все таки отдельная тема, поэтому мы не будем сильно на этом останавливаться сейчас.
Деплоймент
Чтобы собрать и запустить наше приложение в продакшене есть несколько вариантов.
Таким образом сборка и запуск приложения выглядит как:
Для деплоймента этого JAR файла не нужно ничего, кроме установленной Java (JRE). Это так называемый fat JAR — он включает в себя и встроенный сервлет контейнер (Tomcat по умолчанию) и фреймворк, и все библиотеки-зависимости. По сути, он является единственным артефактом деплоймтента — его можно просто копировать на целевой сервер и запускать там.
Более того, файл можно сделать «выполняемым» и запускать его просто из командной строки (Java, конечно, все равно необходима).
На базе этого файла можно легко создать Docker образ или установить его как демон. Больше деталей доступно в официальной документации.
Заключение
Получилось, все же, очень сжато — но уложить даже самый простой вводный курс по Spring в рамки одной статьи не очень просто. Надеюсь, это поможет кому-то сделать первый шаги в Spring-е, и хотя понять его фундаментальные концепции.
Как вы успели заметить, в тексте статьи много раз звучало слово «магия Spring». По сути своей, это очень «магический» фреймворк — даже взглянув на самую верхушку айсберга мы уже видели, что Spring много всего делает в фоне. Это является и плюсом, и минусом фреймворка. Плюс несомненно в том, что многие сложные вещи (очень многие) можно сделать одной аннотацией или зависимостью. Минус же это скрытая сложность — чтобы решить какие-то сложные проблемы, заставить фреймворк работать в крайних случаях или понимать все тонкости и аспекты нужно его неплохо знать.
Чтобы сделать этап «знать» как можно проще, Spring обладает отличной документацией, огромным сообществом, и чистыми исходниками, которые вполне можно читать. Если расположить Spring на шкале Рича Хики, он (Spring) несомненно попадет в easy, но уж точно не simple. Но для современного энтерпрайза (и не только энтерпрайза) он дает невероятные возможности чтобы получить production-ready приложение очень быстро и концентрироваться на логике приложения, а не инфраструктуры вокруг.
Java Blog
Spring Boot инструменты разработчика
Spring Boot включает в себя дополнительный набор инструментов, которые могут сделать процесс разработки приложений более приятным. Модуль spring-boot-devtools может быть включен в любой проект для предоставления дополнительных функций времени разработки. Чтобы включить поддержку devtools, добавьте зависимость модуля в свою сборку, как показано в следующих листингах для Maven и Gradle:
Переупакованные архивы по умолчанию не содержат devtools. Если вы хотите использовать определенную удаленную функцию devtools, вам нужно отключить свойство сборки excludeDevtools, чтобы включить его. Свойство поддерживается как плагинами Maven, так и Gradle.
Свойства по умолчанию
Несколько библиотек, поддерживаемых Spring Boot, используют кэши для повышения производительности. Например, движки шаблонов кэшируют скомпилированные шаблоны, чтобы избежать многократного анализа файлов шаблонов. Кроме того, Spring MVC может добавлять заголовки кэширования HTTP к ответам при обслуживании статических ресурсов.
Хотя кэширование очень полезно в производственной среде, оно может быть непродуктивным во время разработки, мешая вам увидеть изменения, которые вы только что внесли в свое приложение. По этой причине spring-boot-devtools отключает параметры кэширования по умолчанию.
Параметры кэша обычно настраиваются параметрами в вашем файле application.properties. Например, Thymeleaf предлагает свойство spring.thymeleaf.cache. Вместо того, чтобы устанавливать эти свойства вручную, модуль spring-boot-devtools автоматически применяет разумную конфигурацию времени разработки.
Поскольку при разработке приложений Spring MVC и Spring WebFlux требуется больше информации о веб-запросах, инструменты разработчика включат ведение журнала DEBUG для группы веб-журналов. Это даст вам информацию о входящем запросе, какой обработчик его обрабатывает, результат ответа и т. д. Если вы хотите записать все детали запроса (включая потенциально конфиденциальную информацию), вы можете включить spring.http.log-request-details свойство конфигурации.
Если вы не хотите, чтобы свойства по умолчанию применялись, вы можете установить для spring.devtools.add-properties значение false в вашем application.properties.
Полный список свойств, которые применяются devtools, смотрите в DevToolsPropertyDefaultsPostProcessor.
Faster Development with Spring Boot DevTools
How to speed up your Spring Boot development even more with DevTools and make it more enjoyable and productive?
As usually with Spring Boot, the setup is really simple. All you need to do is to add the right dependency, and you are good to go. Spring Boot detects this and auto-configures DevTools accordingly.
If you are using Maven:
Alternatively, when using Gradle:
Note that the dependency is declared as optional. This is important. This prevents DevTools dependency being transitively applied to other modules that depend on your project.
Whenever there is a change in files on your classpath, DevTools automatically restart your running application with the new changes applied. When developing locally, this can be valuable as you don’t need to redeploy your application manually.
On its own, it wouldn’t be so useful as restarts can still take a lot of time. Fortunately, these restarts are way faster than regular restarts because of a clever trick, which DevTools use.
You see, when developing an application, you usually change a class or a few and want to check results in your running application for feedback. You change a tiny fraction of your application as the majority of loaded classes are from frameworks and third party libs.
Triggering a restart in an IDE
When using IntelliJ IDEA, you need to build your project ( Ctrl + F9 or Build → Build Project ). You can also configure IDEA to rebuild automatically. Alternatively, you can open your Spring Boot run configuration and define what happens when you trigger an application update ( Ctrl + F10 ):
In the first combo-box, you can select Update trigger file to trigger DevTools restart whenever you call the Update action. Alternatively, you can even select the option to try Hot Swap and restart using DevTools only if Hot Swap failed.
In the second combo-box, you can configure reloading all the static resources and templates when IDEA window loses focus (for example when switching to a browser window).
In Eclipse it is enough just to save your files.
The usage of the Spring Boot DevTools is intended only for development, not for production. If your application detects you’re running in production, DevTools are automatically disabled.
For this purposes, whenever you run your app as a fully packaged artifact such as a jar with an embedded application server, it is considered to be a production app:
Same applies when your app is started via special classloader, such as on an application server. In contrast, when you run an exploded artifact (such as in your IDE), your application is considered in development mode. The same applies when using spring-boot-plugin to run the application:
Spring DevTools automatically launch a local instance of LiveReload server, which monitors your files. All you need to do is to install a browser extension, and you’re good to go. It is not only useful for developing frontend of your application (in case you distribute it as a part of your Spring app artifact), but it can also be used to monitor and reload output of your REST API.
When developing your application locally, you usually have different configuration needs than when running in production. One example can be caching. When in production, it is crucial to depend on various caches (such as templating engine’s caches, caching headers for static resources and so on). In development, it can make you miserable by serving old data and not reflecting your latest changes. Another example may be enhanced logging, which can be useful in development but too detailed for production.
It is unnecessarily complicated to manage dual sets of configuration by yourself. The good news is that Spring Boot DevTools configure many properties for your local development out of the box.
You can check the list of all the properties in the DevToolsPropertyDefaultsPostProcessor.
In addition to local development, you can also connect to a remote application running DevTools. This is not intended for production environments as it can be a serious security risk. However, it can be very useful in pre-production environments.
Enabling remote connection
Remote connection is not enabled by default. You need to explicitly enable it by modifying your pom file:
Or with gradle, you need to set excludeDevtools = false :
Then you need to set a secret password to be used for authentication when connecting to the remote application
Connecting to a remote app
Once your remote app is running, you can launch a remote connection session. Now all you need to do is to launch org.springframework.boot.devtools.RemoteSpringApplication with URL of your remote app as an argument. Note you should use https if possible.
Running the remote connection is easy in your IDE. In IDEA you need just to create a new run configuration. Go to Run → Edit Configurations. and create a new configuration with the + icon in the upper left corner. Choose Application type.
As the Main class select RemoteSpringApplication from the DevTools module and as a program argument pass URL of your remote app.
After you run this configuration, you should see a similar output if the connection to your remote app is successful.
Once you connect to a remote app, DevTools monitors classpath changes same as it does for local development. However, instead of a local restart, it pushes the changes to the remote server and triggers restart there. This can be a lot faster than building the app and deploying to the remote machine.
You can configure DevTools using configuration properties as you would in any other Spring application. That usually means editing application.properties of your project. This configuration is separate for each application.
Spring app using DevTools automatically launches a LiveReload server. Unfortunately, only one instance of this server can be running at the same time. To be more precise, just the first one will work. That applies not only to multiple instances of Spring apps with DevTools but to any other apps, which are also using LiverReload under the hood, such as Gatsby in development mode.
If you want to configure your Spring app not to launch a LiveReload server, you can do it in your application.properties :
By default, the hook is enabled, so you don’t need to worry about it unless you explicitly disable it.
Collisions with third-party libraries
In case of such conflict, you can disable the automatic restart by setting:
Restart will no longer be triggered. However, the restart classloader will still be used. If you need to disable the classloader completely, you need to do so before launching the app:
Even if you don’t use th automatic restart you can still benefit from the other features DevTools provide.
Enabling lazy initialization
DevTools enables hot restart of your application in the same JVM. A significant benefit of hot restart is that it gives the JIT more of a chance to optimise the code involved in starting your application. After a few restarts, the original time of 2500ms is reduced by almost 80% to nearer 500ms. With lazy initialization, we can do even better. Setting spring.main.lazy-initialization sees our application restart in 400ms directly in the IDE.
Using lazy initialization for all your beans in a production application is questionable. It gives you excellent performance boost for start-up at the expense of longer first requests for individual beans. More importantly, your application does not fail fast anymore. Instead of crashing right when starting the app, it would fail only after directly requesting a misconfigured bean. This can be very dangerous as you would not discover many bugs until it is too late. Still, mass lazy initialization can be useful for speeding up development time as when working on a certain feature you usually work only on a fraction of your application and don’t use the rest. An ideal compromise would be enabling mass lazy initialization for local development only (let’s say using a spring profile) and disable it for deployed higher environments.
DevTools make your development of Spring Boot applications faster and easier by providing automatic restart and LiveReload functionality. I addition to this, it sets various properties to values more suitable for local development. Furthermore, it allows you to remotely connect to your application and still use most of its features. When running in production, DevTools are not used. For detailed information, see the official docs.