Spring Boot vs Spring MVC vs Spring — Как они сравниваются?


image

Spring, Spring Boot, Spring MVC, везде есть слово “spring”! Давайте пройдемся где и когда вы можете применять каждый из этих инструментов


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

Что за основная проблема, которую этот Spring Framework решает?


Долго и упорно подумайте. Какова проблема, решаемая Spring Framework?

Почему это важно? Потому что, когда DI или IOC правильно используются, мы можем разрабатывать слабо связанные приложения. А слабо связанные приложения могут быть легко протестированы юнит-тестами.

Давайте рассмотрим простой пример.

Пример без внедрения зависимостей


Рассмотрим пример ниже: WelcomeController зависит от WelcomeService, чтобы получить приветственное сообщение. Что он делает, чтобы получить экземпляр WelcomeService?

WelcomeService service = new WelcomeService();

Эта строка создает экземпляр данного сервиса. А это значит что они сильно связаны. Например, если я создаю мок для WelcomeService в юнит-тесте для WelcomeController, как мне заставить WelcomeController использовать мок? Не легко!

@RestController
public class WelcomeController {   private WelcomeService service = new WelcomeService();   @RequestMapping("/welcome")
   public String welcome() {
       return service.retrieveWelcomeMessage();
   }
}

Простой пример с внедрением зависимостей


Мир выглядит намного проще с внедрением зависимостей. Вы позволяете Spring Framework делать тяжелую работу. Мы просто используем две простые аннотации: Component и Autowired.

  • Используя Component, мы говорим Spring Framework: Эй там, это бин, которым тебе нужно управлять.
  • Используя Autowired, мы говорим Spring Framework: Эй, найди правильное совпадение для этого конкретного типа и подключи его.

В примере ниже, Spring framework создаст бин для WelcomeService и подключит его к WelcomeController.

В юнит-тесте, я могу попросить Spring framework подключить мок для WelcomeService к WelcomeController. (Spring Boot делает вещи проще делая это с аннотацией @MockBean. Но это уже совсем другая история!)

@Component
public class WelcomeService {
  //Bla Bla Bla
}@RestController
public class WelcomeController {  @Autowired
  private WelcomeService service;  @RequestMapping("/welcome")
  public String welcome() {
      return service.retrieveWelcomeMessage();
  }
}

Что еще решает Spring Framework?


Проблема 1: Дублирование/Загрязнение кода


Останавливается ли Spring Framework с внедрением зависимостей? Нет. Он строится на основной концепции внедрения зависимостей с несколькими модулями Spring

  • Spring JDBC
  • Spring MVC
  • Spring AOP
  • Spring ORM
  • Spring JMS
  • Spring Test

Остановимся на Spring JMS и Spring JDBC на мгновение.

Приносят ли эти модули новую функциональность? Нет. Мы можем делать все это на J2EE или Java EE. Так, что они приносят? Они приносят простые абстракции. Целью этих абстракций является:

  • Уменьшить Boilerplate код/Уменьшить дублирование
  • Способствовать разъединению/Расширить тестируемость

Например, вам надо намного меньше кода, чтобы использовать JDBCTemplate или JMSTemplate по сравнению с традиционным JDBC или JMS.

Проблема 2: хорошее интегрирование с другими фреймворками


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

  • Hibernate для ORM
  • iBatis для Object Mapping
  • JUnit и Mockito для юнит-тестирования

Почему нам нужен Spring Boot?


У приложений, основанных на Spring, много конфигураций.

Когда мы используем Spring MVC, нам необходимо сконфигурировать: component scan, dispatcher servlet, view resolver, web jars(для доставки статического контента) среди других вещей.

<bean
  class="org.springframework.web.servlet.view.InternalResourceViewResolver">
 <property name="prefix">
     <value>/WEB-INF/views/</value>
 </property>
 <property name="suffix">
     <value>.jsp</value>
 </property>
</bean><mvc:resources mapping="/webjars/**" location="/webjars/"/>

Код ниже показывает типичную конфигурацию dispatcher servlet в web приложении.

<servlet>
  <servlet-name>dispatcher</servlet-name>
  <servlet-class>
    org.springframework.web.servlet.DispatcherServlet
  </servlet-class>
  <init-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/todo-servlet.xml</param-value>
  </init-param>
  <load-on-startup>1</load-on-startup>
</servlet><servlet-mapping>
   <servlet-name>dispatcher</servlet-name>
   <url-pattern>/</url-pattern>
</servlet-mapping>

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

<bean id="dataSource"
 class="com.mchange.v2.c3p0.ComboPooledDataSource"
 destroy-method="close">
  <property name="driverClass" value="${db.driver}" />
  <property name="jdbcUrl" value="${db.url}" />
  <property name="user" value="${db.username}" />
  <property name="password" value="${db.password}" />
</bean><jdbc:initialize-database data-source="dataSource">
  <jdbc:script location="classpath:config/schema.sql" />
  <jdbc:script location="classpath:config/data.sql" />
</jdbc:initialize-database><bean
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
 id="entityManagerFactory">
  <property name="persistenceUnitName" value="hsql_pu" />
  <property name="dataSource" ref="dataSource" />
</bean><bean id="transactionManager"class="org.springframework.orm.jpa.JpaTransactionManager">
 <property name="entityManagerFactory" ref="entityManagerFactory" />                                <property name="dataSource" ref="dataSource" />
</bean><tx:annotation-driven transaction-manager="transactionManager"/>

Проблема 1: Spring Boot авто конфигурация: Можем ли мы думать иначе?


Spring Boot приносит новый мыслительный процесс вокруг всего этого.

  • Что насчет авто конфигурации источника данных если jar-файл Hibernate есть в classpath?
  • Что насчет авто конфигурации a Dispatcher Servlet если Spring MVC jar есть в classpath?

Тогда будут положения, для переопределения авто конфигурации по умолчанию.

Проблема 2: Spring Boot Starter Projects: Построен вокруг хорошо известных паттернов


Давайте скажем что хотим разработать веб приложение.

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

У всех веб приложений аналогичные потребности. Ниже перечислены зависимости которые используются в Spring MVC. Они включают в себя Spring MVC, Jackson Databind, Hibernate-Validator и Log4j.

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-webmvc</artifactId>
  <version>4.2.2.RELEASE</version>
</dependency><dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-databind</artifactId>
  <version>2.5.3</version>
</dependency><dependency>
  <groupId>org.hibernate</groupId>
  <artifactId>hibernate-validator</artifactId>
  <version>5.0.2.Final</version>
</dependency><dependency>
  <groupId>log4j</groupId>
  <artifactId>log4j</artifactId>
  <version>1.2.17</version>
</dependency>

Если вы хотите разрабатывать веб приложение или приложение для RESTful сервисов, ваш выбор — Spring Boot Start Web. Давайте быстро создадим проект с Spring Boot Starter Web используя Spring Initializr.

Зависимости для Spring Boot Starter Web


<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
</dependency>

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

image

Зависимости могут быть классифицированы на:

  • Spring: core, beans, context, aop
  • Web MVC: (Spring MVC)
  • Jackson: для JSON связи
  • Валидация: Hibernate Validator, Validation API
  • Embedded Servlet Container: Tomcat
  • Логирование: logback, slf4j

Любое типичное веб приложение будет использовать все эти зависимости. Spring Boot Starter Web поставляется с ними. Как разработчик, мне не нужно беспокоиться об этих зависимостях или о совместимых версиях.

Параметры проекта Spring Boot Starter


Как мы видим из Spring Boot Starter Web, стартовые проекты помогают нам быстро начать разработку определенных типов приложений.

  • spring-boot-starter-web-services: SOAP Web Services
  • spring-boot-starter-web: Web и RESTful приложения
  • spring-boot-starter-test: юнит-тестирование и интеграционное тестирование
  • spring-boot-starter-jdbc: Традиционный JDBC
  • spring-boot-starter-hateoas: Добавить HATEOAS фичи к вашим сервисам
  • spring-boot-starter-security: Аутентификация и Авторизация используя Spring Security
  • spring-boot-starter-data-jpa: Spring Data JPA с Hibernate
  • spring-boot-starter-cache: Enabling Spring Framework’s поддержку кэширования
  • spring-boot-starter-data-rest: Предоставление простых REST сервисов используя Spring Data REST

Другие цели Spring Boot


Также есть несколько стартеров для технических вещей:

  • spring-boot-starter-actuator: Для использования расширенных функций, таких как мониторинг и отслеживание вашего приложение из коробки
  • spring-boot-starter-undertow, spring-boot-starter-jetty, spring-boot-starter-tomcat: Для выбора конкретного встроенного контейнера сервлетов
  • spring-boot-starter-logging: Для логирования используя logback
  • spring-boot-starter-log4j2: Логирование используя Log4j2

Spring Boot направлен на создание приложений более краткие сроки.

  • Actuator: Включает расширенный мониторинг и отслеживание приложений.
  • Embedded Server Integrations: Поскольку сервер интегрирован в приложение, мне необходимо иметь отдельный сервер приложений, установленный на сервере
  • Обработка ошибок по умолчанию

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


  1. GeraJet
    25.12.2019 15:05
    +3

    Перевод просто ужасен!


    1. apapacy
      25.12.2019 17:07

      Автор не говорит что это перевод


      1. silverwolf
        26.12.2019 09:04

        По кривому форматирования кода видно что скопировано, а вот это место показывает что до конца не перевели (я про and).

        Мы просто используем две простые аннотации: Component and Autowired.


      1. olegchir
        27.12.2019 12:13
        +1

        Это перевод вот этой статьи автора David Johnson. Который в свою очередь, вполне возможно, вдохновлялся туториалом SpringBoot For Beginners Ranga Karanam.


        Делать переводы — хорошо.


        Не указывать автора — плохо и стыдно.


  1. apapacy
    25.12.2019 17:06
    -2

    По spreengboot я так понял что основная ориентация это микросервисная архитектура. Поэтому http сервер строки в сам компонент а не должен работать вместе с сервером типа tomcat или glassfish. Это как бы наиболее принципиальное функциональное различие.
    Более того springmvc в настоящее время выглядит как legacy вариант. И это мне не совсем ясно. Так как решение с soringmvc выглядело очень удобным. А тянуть в каждый микросервис хуже пьян java машины с встроенным http сервером как то слишком громоздко


  1. iFebrity
    26.12.2019 16:38

    Spring Boot направлен на производство готовых приложений в сжатый срок.

    Так и запишем


  1. Lizard1 Автор
    27.12.2019 20:10

    Доброго времени суток. Попрошу хейтеров успокоиться, ибо да, это перевод, и изменить «тип» данной статьи уже не могу, сорян. А так хочу сказать спасибо, т.к. вы нашли ошибки, которые я пропустил. Переводил отсюда: medium.com/@sandhya.sandy/spring-boot-vs-spring-mvc-vs-spring-how-do-they-compare-3917c98aff22
    P.S. Впредь буду внимательнее. (Первый пост).