1. Обзор
В этой статье мы рассмотрим основные преимущества Spring как одной из самых популярных сред Java.
Что еще более важно, мы попытаемся понять причины, по которым мы выбрали Spring. Подробная информация о Spring и его составных частях широко освещалась в наших предыдущих уроках . Следовательно, мы пропустим вводные части «как» и сосредоточимся в основном на «почему».
2. Зачем использовать любой фреймворк?
Прежде чем мы начнем какое-либо обсуждение, в частности, Spring, давайте сначала поймем, почему нам вообще нужно использовать какой-либо фреймворк.
Язык программирования общего назначения, такой как Java, способен поддерживать широкий спектр приложений . Не говоря уже о том, что Java активно разрабатывается и совершенствуется каждый день.
Более того, существует бесчисленное множество библиотек с открытым исходным кодом и проприетарных библиотек для поддержки Java в этом отношении.
Так зачем же нам все-таки нужен фреймворк? Честно говоря, нет абсолютной необходимости использовать фреймворк для выполнения задачи. Но часто рекомендуется использовать его по нескольким причинам:
- Помогает нам сосредоточиться на основной задаче, а не на связанном с ней шаблоне.
- Объединяет многолетнюю мудрость в виде шаблонов проектирования
- Помогает нам соблюдать отраслевые и нормативные стандарты
- Снижает общую стоимость владения приложением
Мы только что коснулись поверхности, и мы должны сказать, что преимущества трудно игнорировать. Но это не может быть все плюсы, так что в чем подвох:
- Заставляет нас писать приложение определенным образом
- Привязывается к определенной версии языка и библиотек
- Добавляет к ресурсу приложения
Откровенно говоря, в разработке программного обеспечения нет серебряных пуль, и фреймворки, безусловно, не являются исключением. Таким образом, выбор того, какой фреймворк или нет, должен зависеть от контекста.
Надеюсь, к концу этой статьи мы будем лучше подготовлены к принятию решения относительно Spring в Java.
3. Краткий обзор экосистемы Spring
Прежде чем мы начнем качественную оценку Spring Framework, давайте подробнее рассмотрим, как выглядит экосистема Spring.
Spring появился где-то в 2003 году, когда Java Enterprise Edition быстро развивалась, а разработка корпоративного приложения была захватывающей, но тем не менее утомительной!
Spring начинался как контейнер Inversion of Control (IoC) для Java . Мы по-прежнему связываем Spring в основном с ним, и, по сути, он составляет ядро фреймворка и других проектов, которые были разработаны на его основе.
3.1. Весенний фреймворк
Фреймворк Spring разделен на модули , что упрощает выбор частей для использования в любом приложении:
- Ядро : предоставляет основные функции, такие как DI (внедрение зависимостей), интернационализация, проверка и АОП (аспектно-ориентированное программирование).
- Доступ к данным: поддерживает доступ к данным через JTA (Java Transaction API), JPA (Java Persistence API) и JDBC (Java Database Connectivity).
- Интернет : поддерживает как Servlet API ( Spring MVC ), так и недавно появившийся Reactive API ( Spring WebFlux ), а также дополнительно поддерживает WebSockets, STOMP и WebClient.
- Интеграция : поддерживает интеграцию с корпоративной Java через JMS (служба сообщений Java), JMX (расширение управления Java) и RMI (вызов удаленного метода).
- Тестирование : широкая поддержка модульного и интеграционного тестирования с помощью Mock Objects, Test Fixtures, управления контекстом и кэширования.
3.2. Весенние проекты
Но что делает Spring гораздо более ценным, так это мощная экосистема, которая выросла вокруг него за эти годы и продолжает активно развиваться . Они структурированы как проекты Spring, которые разрабатываются на основе среды Spring.
Хотя список проектов Spring длинный и постоянно меняется, стоит упомянуть несколько:
- Boot : Предоставляет нам набор тщательно продуманных, но расширяемых шаблонов для создания различных проектов на основе Spring практически в кратчайшие сроки. Это позволяет очень легко создавать автономные приложения Spring со встроенным Tomcat или подобным контейнером.
- Облако : обеспечивает поддержку для простой разработки некоторых распространенных шаблонов распределенных систем, таких как обнаружение служб, прерыватель цепи и шлюз API. Это помогает нам сократить усилия по развертыванию таких стандартных шаблонов на локальных, удаленных или даже управляемых платформах.
- Безопасность : предоставляет надежный механизм для разработки аутентификации и авторизации для проектов на основе Spring с широкими возможностями настройки. Благодаря минимальной декларативной поддержке мы получаем защиту от распространенных атак, таких как фиксация сеанса, перехват кликов и подделка межсайтовых запросов.
- Мобильный : Предоставляет возможности для обнаружения устройства и соответствующей адаптации поведения приложения. Кроме того, поддерживается управление представлениями с учетом устройств для оптимального взаимодействия с пользователем, управление предпочтениями сайтов и переключение сайтов.
- Пакетная обработка: предоставляет упрощенную платформу для разработки пакетных приложений для корпоративных систем, таких как архивация данных. Имеет интуитивно понятную поддержку планирования, перезапуска, пропуска, сбора метрик и ведения журнала. Кроме того, поддерживается масштабирование для больших объемов заданий за счет оптимизации и разделения.
Излишне говорить, что это довольно абстрактное введение в то, что может предложить Spring. Но это дает нам достаточно оснований в отношении организации и широты Spring, чтобы продолжить наше обсуждение.
4. Весна в действии
Для понимания любой новой технологии принято добавлять программу hello-world.
Давайте посмотрим, как Spring может упростить написание программы, которая делает больше, чем просто hello-world . Мы создадим приложение, которое будет предоставлять операции CRUD как REST API для объекта домена, такого как Employee, поддерживаемого базой данных в памяти. Более того, мы защитим наши конечные точки мутации, используя базовую аутентификацию. Наконец, ни одно приложение не может быть завершено без старых добрых модульных тестов.
4.1. Настройка проекта
Мы настроим наш проект Spring Boot с помощью Spring Initializr — удобного онлайн-инструмента для начальной загрузки проектов с нужными зависимостями. Мы добавим Web, JPA, H2 и Security в качестве зависимостей проекта, чтобы правильно настроить конфигурацию Maven.
Более подробная информация о начальной загрузке доступна в одной из наших предыдущих статей.
4.2. Модель домена и постоянство
Сделав так мало, мы уже готовы определить нашу модель предметной области и постоянство.
Давайте сначала определим сотрудника
как простую сущность JPA:
@Entity
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@NotNull
private String firstName;
@NotNull
private String lastName;
// Standard constructor, getters and setters
}
Обратите внимание на автоматически сгенерированный идентификатор, который мы включили в определение нашего объекта.
Теперь нам нужно определить репозиторий JPA для нашей сущности. Вот где Spring делает это действительно просто:
public interface EmployeeRepository
extends CrudRepository<Employee, Long> {
List<Employee> findAll();
}
Все, что нам нужно сделать, это определить такой интерфейс, и Spring JPA предоставит нам реализацию, дополненную операциями по умолчанию и пользовательскими операциями . Довольно аккуратно! Подробнее о работе со Spring Data JPA читайте в других наших статьях.
4.3. Контроллер
Теперь нам нужно определить веб-контроллер для маршрутизации и обработки наших входящих запросов:
@RestController
public class EmployeeController {
@Autowired
private EmployeeRepository repository;
@GetMapping("/employees")
public List<Employee> getEmployees() {
return repository.findAll();
}
// Other CRUD endpoints handlers
}
На самом деле все, что нам нужно было сделать, это аннотировать класс и определить метаинформацию о маршрутизации вместе с каждым методом обработчика.
Работа с контроллерами Spring REST подробно описана в нашей предыдущей статье.
4.4. Безопасность
Итак, мы все определили, но как насчет защиты таких операций, как создание или удаление сотрудников? Нам не нужен неаутентифицированный доступ к этим конечным точкам!
Spring Security действительно сияет в этой области:
@EnableWebSecurity
public class WebSecurityConfig
extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http)
throws Exception {
http
.authorizeRequests()
.antMatchers(HttpMethod.GET, "/employees", "/employees/**")
.permitAll()
.anyRequest()
.authenticated()
.and()
.httpBasic();
}
// other necessary beans and definitions
}
Здесь есть дополнительные детали, которые требуют внимания для понимания, но наиболее важным моментом, на который следует обратить внимание, является декларативный способ, в котором мы разрешили только операции GET без ограничений .
4.5. Тестирование
Теперь мы все сделали, но подождите, как мы это проверим?
Давайте посмотрим, сможет ли Spring упростить написание модульных тестов для контроллеров REST:
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
@AutoConfigureMockMvc
public class EmployeeControllerTests {
@Autowired
private MockMvc mvc;
@Test
@WithMockUser()
public void givenNoEmployee_whenCreateEmployee_thenEmployeeCreated() throws Exception {
mvc.perform(post("/employees").content(
new ObjectMapper().writeValueAsString(new Employee("First", "Last"))
.with(csrf()))
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON))
.andExpect(MockMvcResultMatchers.status()
.isCreated())
.andExpect(jsonPath("$.firstName", is("First")))
.andExpect(jsonPath("$.lastName", is("Last")));
}
// other tests as necessary
}
Как мы видим, Spring предоставляет нам необходимую инфраструктуру для написания простых модульных и интеграционных тестов , которые в противном случае зависят от контекста Spring, который необходимо инициализировать и настроить.
4.6. Запуск приложения
Наконец, как нам запустить это приложение? Это еще один интересный аспект Spring Boot. Хотя мы можем упаковать это как обычное приложение и развернуть традиционно в контейнере сервлетов.
Но где же это весело! Spring Boot поставляется со встроенным сервером Tomcat :
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Это класс, который предварительно создается как часть начальной загрузки и содержит все необходимые сведения для запуска этого приложения с использованием встроенного сервера.
Кроме того, это очень настраиваемый .
5. Альтернативы Spring
Хотя выбор использования фреймворка относительно проще, выбор между фреймворками часто может быть пугающим из-за того, что у нас есть выбор. Но для этого у нас должно быть хотя бы приблизительное представление о том, какие существуют альтернативы функциям, которые может предложить Spring.
Как мы обсуждали ранее, среда Spring вместе с ее проектами предлагает корпоративному разработчику широкий выбор . Если мы быстро оценим современные Java-фреймворки, то увидим, что они даже близко не подходят к той экосистеме, которую нам предоставляет Spring.
Однако для конкретных областей они являются убедительным аргументом в пользу выбора в качестве альтернативы:
- Guice : предлагает надежный контейнер IoC для приложений Java.
- Игра : вполне подходит для использования в качестве веб-фреймворка с реактивной поддержкой.
- Hibernate : установленная структура для доступа к данным с поддержкой JPA.
Помимо этого, есть несколько недавних дополнений, которые предлагают более широкую поддержку, чем конкретный домен, но все же не охватывают все, что может предложить Spring:
- Micronaut : платформа на основе JVM, адаптированная к облачным микросервисам.
- Quarkus : стек Java новой эры, который обещает обеспечить более быструю загрузку и меньшую занимаемую площадь.
Очевидно, что нет ни необходимости, ни возможности полностью перебирать список, но здесь мы улавливаем общую идею.
6. Итак, почему стоит выбрать весну?
Наконец, мы создали весь необходимый контекст для ответа на наш главный вопрос: почему Spring? Мы понимаем, как фреймворк может помочь нам в разработке сложных корпоративных приложений.
Более того, мы понимаем варианты, которые у нас есть для конкретных задач, таких как Интернет, доступ к данным, интеграция с точки зрения фреймворка, особенно для Java.
Где среди всего этого сияет Весна? Давайте исследовать.
6.1. Удобство использования
Одним из ключевых аспектов популярности любого фреймворка является простота его использования разработчиками. Переход через несколько вариантов конфигурации и Соглашение по конфигурации позволяет разработчикам действительно легко начать, а затем настроить именно то, что им нужно .
Такие проекты, как Spring Boot, сделали начальную загрузку сложного проекта Spring почти тривиальной задачей . Не говоря уже о том, что у него есть отличная документация и учебные пособия, которые помогут любому освоиться.
6.2. Модульность
Еще одним ключевым аспектом популярности Spring является его модульная природа. У нас есть варианты использования всей среды Spring или только необходимых модулей. Более того, мы можем дополнительно включить один или несколько проектов Spring в зависимости от необходимости.
Более того, у нас есть возможность использовать и другие фреймворки, такие как Hibernate или Struts!
6.3. Соответствие
Хотя Spring не поддерживает все спецификации Jakarta EE, он поддерживает все свои технологии , часто улучшая поддержку по сравнению со стандартной спецификацией, где это необходимо. Например, Spring поддерживает репозитории на основе JPA и, следовательно, упрощает переключение поставщиков.
Кроме того, Spring поддерживает отраслевые спецификации, такие как Reactive Stream в Spring Web Reactive и HATEOAS в Spring HATEOAS .
6.4. Тестируемость
Принятие любого фреймворка во многом также зависит от того, насколько легко тестировать приложение, построенное на его основе. Spring в своей основе защищает и поддерживает разработку через тестирование (TDD).
Приложение Spring в основном состоит из POJO, что, естественно, значительно упрощает модульное тестирование. Однако Spring предоставляет Mock Objects для таких сценариев, как MVC, где в противном случае модульное тестирование усложняется.
6.5. Зрелость
Spring имеет долгую историю инноваций, внедрения и стандартизации. За прошедшие годы он стал достаточно зрелым, чтобы стать стандартным решением для большинства распространенных проблем , возникающих при разработке крупномасштабных корпоративных приложений.
Что еще более интересно, так это то, насколько активно он разрабатывается и поддерживается. Поддержка новых языковых функций и решений для корпоративной интеграции разрабатываются каждый день.
6.6. Поддержка сообщества
И последнее, но не менее важное: любой фреймворк или даже библиотека выживает в отрасли благодаря инновациям, и нет лучшего места для инноваций, чем сообщество. Spring — это проект с открытым исходным кодом , возглавляемый Pivotal Software и поддерживаемый большим консорциумом организаций и отдельных разработчиков .
Это означает, что он остается контекстуальным и часто футуристическим, о чем свидетельствует количество проектов под его эгидой.
7. Причины не
использовать Spring
Существует широкий спектр приложений, которые могут извлечь выгоду из различных уровней использования Spring, и они меняются так же быстро, как растет Spring.
Однако мы должны понимать, что Spring, как и любой другой фреймворк, помогает управлять сложностью разработки приложений. Это помогает нам избежать распространенных ошибок и обеспечивает удобство сопровождения приложения по мере его роста с течением времени.
Это происходит за счет дополнительных ресурсов и кривой обучения , какой бы небольшой она ни была. Если действительно есть приложение, которое достаточно простое и не должно становиться сложным, возможно, было бы лучше вообще не использовать какой-либо фреймворк!
8. Заключение
В этой статье мы обсудили преимущества использования фреймворка в разработке приложений. Далее мы кратко обсудили Spring Framework, в частности.
Говоря об этом, мы также рассмотрели некоторые альтернативные фреймворки, доступные для Java.
Наконец, мы обсудили причины, которые могут заставить нас выбрать Spring в качестве предпочтительной среды для Java.
Тем не менее, мы должны закончить эту статью советом. Как бы убедительно это ни звучало, обычно в разработке программного обеспечения не существует единого универсального решения .
Следовательно, мы должны применить нашу мудрость в выборе самых простых решений для конкретных проблем, которые мы стремимся решить.