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


Оглавление
  1. Внедрение зависимостей, контейнер, IoC, бины
  2. AOP (аспектно-ориентированное программирование)
  3. JDBC, транзакции, JPA, Spring Data
  4. Spring Boot
  5. Spring MVC
  6. Spring Security
  7. REST
  8. Тестирование




Вопросы


Что такое Spring Boot?

Spring Boot — это набор уже настроенных модулей которые работают в Spring Framework и упрощают конфигурирование Spring приложения.


Вот некоторые центральные модули:


  • Spring-boot-dependencies. Содержит версии зависимостей.
  • Spring-boot-starter-parent. Родительский pom.xml
  • Spring-boot-starters. Родительский модуль для стартеров
  • Spring-boot-autoconfigure. Содержит модули для автонастройки стартеров
  • Spring-boot-actuator. Позволяет мониторить приложение и управлять его созданием

Какие преимущества у Spring Boot?
  • Автоконфигурирование многих настроек, что позволяет избежать шаблонного кода
  • Позволяет легко конфигурировать приложение, когда настройки по умолчанию не устраивают
  • Проект на Spring Boot может компилироваться в автономный JAR-файл
  • Предоставляет набор зависимостей, которые уже проверены на правильную работу друг с другом
  • Имеет встроенные веб-контейнеры, которые позволяют легко тестировать приложение

Как он работает? Как он понимает что и как нужно сконфигурировать?

Он предполагает что вам надо, основываясь на зависимостях в classpath. “Соглашение над конфигурацией” — он автоконфигурирует Spring специально подобранными настройками, которые потом можно переопределить.


Для этого есть несколько аннотаций, @ConditionalOnClass, @ConditionalOnBean, @ConditionalOnMissingBean и @ConditionalOnMissingClass, которые позволяют применять условия к @Configuration-классам и @Bean-методам в этих классах.


Например:


  • Бин будет создан только если определенная зависимость есть в classpath.


    Используйте @ConditionalOnClass, установив туда имя класса из classpath.


  • Бин будет создан только если в контейнере нет бина такого типа или с таким именем.


    Используйте @ConditionalOnMissingBean, установив туда имя или тип бина для проверки.



Что влияет на настройку Spring Boot?

Существует список аннотаций-условий, каждая из которых используется для управления созданием бинов. Вот список таких аннотаций(на самом деле их больше):


Аннотация
Условие прохождения
@ConditionalOnClass
Пристутствие класса в classpath
@ConditionalOnMissingClass
Отсутствие класса в classpath
@ConditionalOnBean
Присутствие бина или его типа(класс бина)
@ConditionalOnMissingBean
Отсутствие бина или его типа
@ConditionalOnProperty
Присутствие Spring-свойства
@ConditionalOnResource
Присутствие файла-ресурса
@ConditionalOnWebApplication
Если это веб-приложение, будет использоваться WebApplicationContext
@ConditionalOnNotWebApplication
Если это не веб-приложение

Как определяются property? Где находится дефолтный PropertySource в Spring Boot?

Spring Boot использует особый порядок PropertySource’ов для того чтобы позволить переопределять значения свойств. Вот порядок источников для получения свойств приложения:


  1. Общие настройки из директории ~/spring-boot devtools.properties
  2. Настройки из аннотации @TestPropertySource из тестов
  3. Атрибуты @SpringBootTest#properties
  4. Аргументы командной строки
  5. Свойства из SPRING_APPLICATION_JSON
  6. Параметры для инициализации ServletConfig
  7. Параметры для инициализации ServletContext
  8. JNDI-атрибуты из java:comp/env
  9. Java System Properties(System.getProperties())
  10. Переменные ОС
  11. RandomValueProperySource
  12. Проперти для профилей, например YAML или application-{profile}.properties
  13. application.properties и YAML не из вашего jar
  14. application.properties и YAML из вашего jar
  15. Аннотация @PropertySource на @Configuration-классе
  16. Проперти по умолчанию(устанавливаются через SpringApplication.setDefaultProperties())

Также добавлю, что property.yml всегда переопределяют property.properties.


Опишите основные аннотации и конфиги для Spring Boot?

Аннотация @SpringBootApplication предоставляет 3 свойства:


  • @EnableAutoConfiguration — включает механизм Spring Boot’а для автоконфигурации
  • @ComponentScan — включает сканирование компонентов в package’е класса где она находится
  • @Configuration — позволяет регистрировать доп. бины в контексте

Вот другие основные аннотации:


@EnableConfigurationProperties — позволяет использовать бины с аннотацией @ConfigurationProperties


@ConfigurationProperties — позволяет связывать проперти из файлов с бинами


@WebMvcTest — используется для тестов Spring MVC


@SpringBootTest — используется, когда нужны функции Spring Boot в тестах


@DataJpaTest — используется для теста компонентов JPA


В чем различия между встроенным контейнером и WAR?

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


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


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


Какие встроенные контейнеры поддерживает Spring?

Spring Boot поддерживает Tomcat, Jetty, и Undertow.
По умолчанию используется TomCat. Для того чтобы изменить контейенер, просто добавьте нужную зависимость в pom.xml.


Что делает @EnableAutoConfiguration?

Она позволяет использовать автоконфигурацию. Автоконфигурация в Spring Boot пытается создать и настроить бины основываясь на зависимостях в classpath, для того чтобы позволить разработчику быстро начать работать с различными технологиями и убрать шаблонный код.


Делает ли Spring Boot сканирование компонентов? Где он их ищет по умолчанию?

Да, делает, если стоит аннотация @SpringBootApplication, которая содержит аннотацию @ComponentScanning.


По умолчанию Spring ищет бины в том же package, что и класс с аннотацией. Это можно переопределить, указав классы(или package) в параметрах scanBasePackageClasses или scanBasePackage.


Что такое Spring Boot Starter POM? Чем он может быть полезен?

Стартеры предоставляют набор удобных дескрипторов зависимостей, которые можно включить в ваше приложение. Вы получаете один источник для spring и связанных с ним технологий без необходимости искать и копипастить дескрипторы развертывания.
Например, если вы хотите начать работать с Spring JPA, всего лишь добавьте зависимость spring-boot-starter-data-jpa в ваш проект.


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


Можете ли вы контролировать логгирование через Spring Boot?

Да. По умолчанию, сообщения с приоритетами ERROR, WARN, INFO будут выводится в приложении. Чтобы включить вывод уровней DEBUG или TRACE вы должны использовать ключи --debug/--trace или установить проперти-свойства debug/trace = true.


logging.level.root = WARN
logging.level.org.springframework.web = DEBUG
logging.level.org.hibernate = ERROR

По умолчанию Sprin Boot логирует только в консоль. Если вы хотите логировать события в файл, необходимо установить свойства logging.file или logging.path в true(например, в application.properties).


Цветной вывод сообщений в журнал


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


logging.pattern.console=%clr(%d{yyyy-MM-dd HH:mm:ss}) {yellow}

Если вы хотите, чтобы записать шла в другие файлы, вы также можете это настроить(YAML):


logging:
  path: /var/logs/
  file: bookWarn.log
  level: 
    root: WARN
    org.
      springframework:
        security: DEBUG

Комментарии (8)


  1. mmMike
    14.10.2019 06:03
    +1

    Очень не однозначное впечатление от статьи.
    Стиль вопросов/ответов как бы подразумевает запоминание без понимания.
    Слова "магия spring boot" как раз из этого корня.


    Не с конкретных "магических" свойств нужно начинать изучение. А из общего понимания.
    Что Spring Boot это всего лишь довольно простое ядро (контенеры) и куча адаптированных для того что бы не конфиликтовали между собой "библиотек".
    Которые никто не мешает использовать и в не Spring framework.


    Один из ярких примеров — вопрос про логирование. SpringBoot? Представляю какая каша в голове возникнет у джунов.


    Какие преимущества у Spring Boot?

    IMHO: Основное преимущество — то что библиотеки между собой не так конфиликтуют, когда пытаешься эту солянку использовать отдельно (точнее меньше с этим проблем).


    А пункт "Проект на Spring Boot может компилироваться в автономный JAR-файл" вообще удивил и заставил улыбнуться.
    А ведь кто то заучивать будет это для собеседования...


    1. Anton23
      14.10.2019 08:16

      Согласен. Меня тоже некоторые вещи удивили, но я старался ничего не менять в переводе.

      Основное преимущество — то что библиотеки между собой не так конфиликтуют, когда пытаешься эту солянку использовать отдельно (точнее меньше с этим проблем).

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

      Один из ярких примеров — вопрос про логирование. SpringBoot? Представляю какая каша в голове возникнет у джунов.

      Про логирование — в доке от Pivotal действительно есть вопрос «Can you control logging with Spring Boot? How?»


    1. PqDn
      14.10.2019 13:01

      Согласен, лучше джуну расти на видяшках от Евгения Борисова.
      В частности по Spring Boot у него достаточно хорошо раскрывается магия стартеров.

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

      А так вообще респект автору за перевод.


    1. xspider2000
      17.10.2019 10:26

      Главное преимущество — это все же готовые конфигурации, а помимо этого два других: отсутствие конфликтов версий библиотек и возможность создания одного standalone jar-файла.


      1. mmMike
        17.10.2019 13:44

        возможность создания одного standalone jar-файла.

        Вообще то, единый jar файл можно создать практически в любом проекте с любым набором famework и библиотек (maven-assembly-plugin). Это такое же никакое отношение имеет к SpringBoot как логгер (который не имеет прямого отношения framework).


        готовые конфигурации

        Готовые конфигурации — это дело наживное. Когда много наработок в разных framwork, то они как бы уже есть.


        Самое главное, из моего опыта, это отсутствие конфиликтов библиотек. Как только начинаешь делать что то более менее сложное (разные реализации Java EE в одной программе, например) — начинаются пляски с бубном (особенно когда нужно общий jar файл сделать).


  1. olegnyr
    17.10.2019 10:27

    Тема сканирования не до конца раскрыта, что значит если есть в classpach? Магии там нет


    1. Anton238 Автор
      17.10.2019 10:28

      что значит если есть в classpach


      Classpath — импорты в приложении. Spring Boot проверяет это с помощью Conditional-аннотаций.
      Если вы импортируете какие-нибудь классы, то spring это заметит и настроит некоторые бины.


      1. olegnyr
        17.10.2019 12:20

        Spring boot работает аналогично механизму ServiceLoader сканируется файл classpath://META-INF/spring.factories. Получаем список классов AutoConfiguration, и только потом уже на каждый класс прогоняем через список фильтров, которые по своим критериям выбирают будут они использоваться для формирования контекста или нет