зачем нужен spring java
Введение в Spring, или что делать, если по всему проекту @Autowired и @Component, а вы не понимаете, что это
Приветствую тебя, Хабр!
Эта статья будет полезна тем, кто уже начал изучать Java и даже успел добиться некоторых успехов в понимании Java Core, и вот услышал слово Spring. И, возможно, даже не один раз: знание Spring Framework, как минимум, фигурирует в описаниях множества вакансий для джавистов. Эта статья поможет вам взобраться на самую первую ступеньку: понять общую идею столь популярного фреймворка.
Начнем издалека. Существует такое понятие как Inversion of Control, по-русски – Инверсия управления, сокращенно – IoC. IoC — один из принципов, приближающий наш код к слабосвязанности. IoC — это делегирование части наших обязанностей внешнему компоненту.
Существуют разные реализации IoC подхода, нас интересует одна из них — Dependency Injection, внедрение зависимостей. Что это такое, название говорит само за себя, так что раскрыть ее я постараюсь на примере. Мы пишем приложение, автоматизирующее работу сети магазинов. Есть классы Shop (магазин) и Seller (продавец). У класса Seller имеется поле типа Shop — магазин, в котором работает продавец. Вот мы и столкнулись с зависимостью: Seller зависит от Shop. Теперь задумаемся, как в объект Seller попадет объект Shop? Есть варианты:
Перечисленные два способа — это реализация Dependency Injection (но пока еще это не IoC). И, наконец, мы подобрались к спрингу: он предоставляет еще один способ внедрять зависимости (а тут уже IoC).
Вообще говоря, Spring — это очень широкий набор библиотек на многие случаи жизни. Существует и Spring MVC для быстрого создания веб-приложений, и Spring Security для реализации авторизации в приложении, и Spring Data для работы с базами данных и еще куча всего. Но отдельно стоит Spring IoC — это базовый вид спринга, который реализует изучаемую нами тему — внедрение зависимостей. Spring IoC заслуживает внимания в самом начале изучения библиотек спринга по еще одной причине. Как вы увидите в процессе практической работы с другими видами спринга, для всех остальных спрингов Spring IoC используется как каркас.
Знакомство со Spring IoC начнем с главного термина: бин (англ. — bean). Самыми простыми словами,
Бин — создаваемый Spring-ом объект класса, который можно внедрить в качестве значения поля в другой объект.
Бин — объект класса, представляющий собой завершенный программный элемент с определенной бизнес-функцией либо внутренней функцией Spring’а, жизненным циклом которого управляет контейнер бинов.
Как вы уже поняли, для того, чтобы в Seller можно было внедрить Shop, Shop должен стать бином. Существует несколько способов рассказать приложению, какие объекты имеют гордое право называться бинами, все они приводят нас к понятию ApplicationContext. ApplicationContext — это сердце спринга. Как правило, он создается в самом начале работы приложения («поднимается») и управляет жизненным циклом бинов. Поэтому его еще называют контейнером бинов.
Подбираемся к главному. Каким образом нам необходимо переписать наши классы, чтобы Spring IoC и его слуга ApplicationContext подставили значение поля Shop объекту Seller? Вот таким:
Просто? Куда уж проще! Элегантно? Вполне. Здесь произошло следующее: аннотация Component сказала спрингу, что класс, который ей аннотируем, это бин. Аннотация Autowired попросила Spring в поле, которое она аннотирует, подставить значение. Эта операция называется «инжектнуть» (inject). Какое именно значение будет подставлено? Об этом чуть позже, сначала разберемся, как вообще классы становятся бинами.
Мы уже знаем, что в начале работы приложения должен подняться хранитель всех бинов ApplicationContext. Он-то и создает сразу все бины. Почти все. Дело в том, что по умолчанию любой бин имеет внутриспринговое свойство scope в значении singleton. Внутриспринговое, так как синглтоном в прямом смысле слова он не является. Он является синглтоном для спринга: при поднятии контекста Spring создаст ровно один объект-бин из указанного класса. Если вы хотите изменить такое поведение — пожалуйста, Spring разрешает управлять временем создания бина и их количеством для одного класса, но сейчас не об этом.
Итак, при поднятии ApplicationContext создаются все бины. Давайте выясним, а собственно где живет контекст и самое главное: как он определяет, из каких классов необходимо создавать бины. Вариантов несколько, для простоты изложения мы поговорим про один из них: конфигурирование с помощью файла xml. Вот его пример:
В этом файле продемонстрирован запуск создания бинов двумя путями. Первый, скажем так, ручной. Видите, здесь есть тег bean с указанием класса. Это и есть бин. Из всего, что прописано в этом файле с тегом bean, будут созданы бины.
Второй путь менее многословен. Помните, над классами мы поставили аннотацию Component. Из всех классов, аннотированных этой аннотацией, будут созданы бины. Благодаря этой строке из xml-файла:
Она говорит спрингу: просканируй весь пакет main и из всего, над чем будет стоять аннотация Component (или другие аннотации, являющиеся наследниками Component), создай бины. Компактно, не правда ли? Просто говорим, в каких пакетах содержатся классы, из которых нужно создавать бины, и аннотируем эти классы.
Поднять контекст с использованием xml-файла можно следующей строчкой кода:
где beans.xml — путь к xml-нику, о котором шла речь выше.
С созданием бинов разобрались. Каким же образом Spring заполнит поле Shop при создании Seller’а? При поднятии контекста создается бин-объект класса Shop. Также создается бин-объект класса Seller, он же тоже аннотирован Component. У него есть поле типа Shop, аннотированное Autowired. Аннотация Autowired говорит спрингу: в это поле нужно инжектнуть бин. В нашем случае у нас есть всего один бин, подходящий на эту роль, то есть тип которого совпадает с типом поля: это бин — экземпляр класса Shop. Он и будет проинжектен в объект Seller, что и требовалось. Я понимаю, сейчас вопросики полезли как червячки: а что будет, если Spring не найдет нужный бин, или найдет несколько подходящих (особенно учитывая, что инжектить можно также по интерфейсу, а не по классу). Spring умен, но требует того же и от нас. Нам нужно либо иметь в системе ровно один бин, подходящий под каждый Autowired, либо обучать Spring действиям при таких конфликтах (об этом мы сейчас не будем, вы и так устали, крепитесь, статья подходит к концу).
Заметьте, что Seller – это тоже бин. Если бы он был не бином, а создавался через new, то автоматически бы ничего в него не проинжектнулось.
Возможно вы сейчас думаете, зачем все эти сложности. Но представьте, что у нас приложение не из 2 классов, а на несколько порядков больше и управление зависимостями уже становится не самой тривиальной задачей.
Возможно вы сейчас думаете, как красиво, просто и лаконично Spring позволяет внедрять зависимости. Но представьте, что что-то пошло не так и вам необходимо дебажить приложение. И все становится уже не так просто…
Парочка хинтов напоследок:
Это легальный способ получить бин, хотя в современных реалиях так обычно не делают. Но для учебного примера можно.
UPD (20.04.2021). Dependency Injection это не всегда IoC! В самом начале я как раз привожу примеры Dependency Injection, не являющиеся IoC.
Обратная сторона Spring
Неделя Spring на Хабре, судя по всему, открыта. Хочется сказать спасибо переводчику и комментаторам статьи «Почему я ненавижу Spring», которая не смотря на сильный негативный посыл в названии вызвала ряд интересных дискуссий, а так же тем, кто отреагировал на мою прошлую статью Как писать на Spring в 2017. Во многом благодаря комментариям к прошлой статье и появилась эта.
В этот раз мы погрузимся в пучины Spring фреймворка, разоблачим его магию, посмотрим как базовое веб приложение выглядит изнутри, и разберемся, какую-же задачу и как решает Spring Boot.
В комментариях к предыдущей статье несколько человек очень справедливо указали, что пример Hello World-а на Spring все же не очень показателен. Spring, особенно с использованием Spring Boot, дает ощущение простоты и всемогущества, но непонимание основ и внутренностей фреймворка ведет к большой опасности получить стектрейсом по логу. Что ж, чтобы немного развеять ощущение полной магии происходящего, сегодня мы возьмем приложение из предыдущей статьи и разберем, как и что происходит внутри фреймворка и от каких проблем нас отгораживает Boot. Целевая аудитория все же начинающие разработчики, но с некоторым опытом и базовыми знаниями Java и Spring. Хотя, возможно, и опытным пользователям Spring будет интересно освежить знания того, что происходит под капотом.
Ключевые понятия
Начнем срывать покровы с самых базовых понятий Spring. Бин (bean) — это не что иное, как самый обычный объект. Разница лишь в том, что бинами принято называть те объекты, которые управляются Spring-ом и живут внутри его DI-контейнера. Бином является почти все в Spring — сервисы, контроллеры, репозитории, по сути все приложение состоит из набора бинов. Их можно регистрировать, получать в качестве зависимостей, проксировать, мокать и т.п.
DI контейнер
Ключевой и фундаментальный механизм Spring. Внешне очень простой, но внутри он предоставляет очень много механизмов для тонкой настройки зависимостей. По сути, любое приложение Спринг — это набор бинов, связанных вместе через DI контейнер.
Еще один очень важный момент, который многие упускают при обсуждении DI контейнера, это то, что использование инъекции зависимостей не подразумевает создания интерфейсов для каждого компонента. Это очень простая мысль, но я много раз видел, что из-за своей простоты она не всегда очевидна. Более того, создание интерфейса, если у него лишь одна реализация — считается плохой практикой. Т.е. классы вполне могут сами по себе быть объектами DI. Более того, отсутствие интерфейса даже не мешает их мокать в тестах, т.к. Mockito, например, вполне умеет мокать классы.
Контекст
Конфигурация
Итак, если приложение — это набор бинов, чтобы оно заработало нам нужно этот набор описать.
Конфигурация — это просто описание доступных бинов. Spring дает несколько вариантов, как можно описать набор бинов, которые сформируют приложение. Исторический вариант — это через набор xml файлов. В наши дни ему на смену пришли Java аннотации. Spring Boot построен на аннтациях чуть более, чем полностью и большинство современных библиотек в принципе тоже можно сконфигурить через аннотации. В третьем своем поколении, конфигурация бинов пришла к подходу функциональной регистрации (functional bean registration), которая станет одной из важных новых фич готовящегося к выходу Spring 5.
Типичный класс конфигурации может, выглядеть, например так:
Эта конфигурация определяет два бина, причем второй зависит от первого. И здесь в игру вступит Spring – когда мы просим предоставить инстанс PaymentProvider — Spring найдет его в контексте и предоставит нам.
Конфигурацию не обязательно описывать в одном огромном файле, можно разбить на несколько и объединять их с помощью @Import аннотаций.
Сканирование компонентов
Резюме
Spring Boot
Теперь переходим к следующей части. Допустим, нам надо сконфигурить подключение к MySQL базе данных. Если мы хотим использовать Spring Data JPA с Hibernate в качестве провайдера, нам потребуется сконфигурировать несколько бинов — EntityManagerFactory (основной класс JPA), DataSource для подключения непосредственно к базе через JDBC драйвер и т.п. Но с другой стороны, если мы это делаем каждый раз и, по сути, делаем одно и то же — почему бы это не автоматизировать? Скажем, если мы указали строку подключения к базе и добавили зависимость на MySQL драйвер — почему бы чему-то автоматически не создать все нужные бины для работы с MySQL? Именно это и делает Spring Boot. По сути, Spring Boot это просто набор классов конфигурации, которые создают нужные бины в контексте. Точно так же их можно создать руками, просто Boot это автоматизирует.
Автоконфигурация
Важное понятие Spring Boot это автоконфигурация. По сути, это просто набор конфигурационных классов, которые создают и регистрируют определенные бины в приложении. По большому счету, даже сам Embedded Servlet Container — это просто еще один бин, который можно сконфигурировать! Пара важных моментов, которые важно знать об автоконфигурации:
Условия и порядок регистрации бинов
Логика при регистрации бинов управляется набором @ConditionalOn* аннотаций. Можно указать, чтобы бин создавался при наличии класса в classpath ( @ConditionalOnClass ), наличии существующего бина ( @ConditionalOnBean ), отсуствии бина ( @ConditionalOnMissingBean ) и т.п.
Spring Boot активно использует эти аннотации чтобы оставаться как можно более незаметным и не перекрывать пользовательские конфигурации.
Погружение в Hello World
Теперь, имея в запасе базовые теоретические знания, разберем что же происходит при запуске приложения.
Итак, наше приложение включает такой код:
Давайте разберем что здесь происходит по шагам.
Класс DemoApplication
Т.е. наличие @SpringBootApplication включает сканирование компонентов, автоконфигурацию и показывает разным компонентам Spring (например, интеграционным тестам), что это Spring Boot приложение
SpringApplication.run()
То получим точно такое же работающее приложение, т.к. класс AnnotationConfigEmbeddedWebApplicationContext найдет в контексте бин типа EmbeddedServletContainerFactory и через него создаст и запустит встроенный контейнер. Обратите внимание, что все это работает в рамках общего DI контейнера, то есть этот класс можно реализовать самим.
@EnableAutoConfiguration
Эта аннотация включает автоконфигурацию. И здесь, пожалуй, ключевой момент в развенчании магии Spring. Вот как объявлена эта аннотация:
Т.е. это самый обычный импорт конфигурации, про который мы говорили выше. Класс же EnableAutoConfigurationImportSelector (и его преемник в Spring Boot 1.5+ — AutoConfigurationImportSelector ) это просто конфигурация, которая добавит несколько бинов в контекст. Однако, у этого класса есть одна тонкость — он не объявляет бины сам, а использует так называемые фабрики.
Класс EnableAutoConfigurationImportSelector смотрит в файл spring.factories и загружает оттуда список значений, которые являются именами классов (авто)конфигураций, которые Spring Boot импортирует.
Т.е. аннотация @EnableAutoConfiguration просто импортирует все перечисленные конфигурации, чтобы предоставить нужные бины в контекст приложения.
По сути, ее можно заменить на ручной импорт нужных конфигураций:
Однако, особенность в том, что Spring Boot пытается применить все конфигурации (а их около сотни). Я думаю, у внимательного читателя уже появилась пара вопросов, которые стоит прояснить.
«Но это же медленно!». И да, и нет — под рукой нет точных цифр, но сам по себе процесс автоконфигурации очень быстрый (порядка сотни миллисекунд на абстрактной машине в вакууме)
Краткое резюме
В основе «магии» Spring Boot нет ничего магического, он использует совершенно базовые понятия из Spring Framework. В кратком виде процесс можно описать так:
Это может выглядеть сложно, но по большей части разработчикам приложений влезать во внутренности автоконфигурации не нужно, если речь не идет о поддержке авто-конфигурации для своей библиотеке.
Диагностика
Auto-configuration report
В ответ Spring выдаст детальный Auto-configuration report:
Строчка в Positive / Negative matches будет для каждой примененной автоконфигурации, более того, Boot сообщит, почему тот или иной бин был создан (т.е. укажет, какие из условий регистрации были выполнены).
Actuator
Spring Boot Actuator это мощный инструмент диагностики работающего приложения, который умеет давать много полезной аналитики (более того, набор этих метрик можно легко расширять из приложения).
Резюме
Spring все же остается большим и не самым простым фреймворком, но это цена высокоуровневых абстракций, которые он предоставляет. И хотя знать все тонкости работы фреймворка в ежедневной разработке не нужно, знать, как он работает изнутри, все же, полезно. Надеюсь, что эта статья помогла понять важность и ценность Spring именно как экосистемы и убрала немного «магичности» в происходящем, особенно при использовании Spring Boot. Мой совет — не бойтесь углубляться в недра фреймворка, читайте исходники и документацию, благо они у Spring-a почти эталонные, на мой взгляд.
Что такое Spring Framework и для чего он нужен?
Введение
Spring-фреймворк обеспечивает комплексную программную и конфигурационную модель для современных Java-enterprise приложений. Ключевой элемент Spring это инфраструктурная поддержка приложений таким образом, чтобы команда разработчиков могла сфокусироваться на бизнес логике приложения которое они пишут, а не на технических деталях платформы на которую они устанавливают приложение.
Возможности
Все доступные фичи и модули описаны по ссылке overview-modules
Минимальные требования
Простейший пример dependency injection
Создадим maven проект с зависимостью от Spring
При этом подключим spring-context. Это один из основных модулей, который предоставляет нам механизмы dependency injection.
Создадим сущность MessagePrinter
Это класс который имеет зависимость от сервиса MessageService
Создадим и сам сервис MessageService
Далее нам понадобиться магия Spring, чтобы связать их вместе
Пример показывает концепцию Dependency Injection в действии, MessagePrinter отвязан(decoupled) от реализации MessageService при этом Spring Framework связывает эти классы вместе в конфигурации которая задается в Application классе.
Вы можете скачать рабочий пример кода по следующей ссылке spring-di-example
Updated: November 06, 2016
Share on
Leave a Comment
You May Also Enjoy
Как писать хорошие тесты?
Создание тестов для программ которые мы создаем это хорошо. Но не менее важно не просто писать тесты, а писать Хорошие тесты.
Ваше первое Angular2 приложение с помощью CLI
В статье будет представлен пример создания Angular2-приложения с помощью CLI
Как очень быстро удалить файлы из каталога в Windows7?
less than 1 minute read
Некоторые программы создают файлы с очень длинными именами или очень много файлов, например node_modules
Что каждый программист должен знать о цифрах с плавающей точкой?
В статье будет представлен пример того, какие нюансы нужно учитывать работая с float и double в Java
Spring Java: основы и уроки для начинающих
Содержание
На сегодняшний день практически для всех приложений используют скриптовый метод программирования – Spring Java. Основное преимущество данного языка заключается в том, что пользователю предоставляется возможность разработать программу в виде простого набора loose-coupled элементов, не привязанных друг к другу.
Проще говоря, чем меньше блоки приложения связаны между собой, тем легче прописать новый функционал и при этом контролировать уже существующую структуру. Одним из наиболее ярких и простых примеров является руководство транзакциями. С помощью Spring Java управление структурой транзакции осуществляет независимо от главной логики связанности с БД. Какие-либо изменения конструкции логики не повлияют на транзакционность, то есть не нарушат основную идею программы. Spring обладает модульностью.
Различные элементы и структуры можно удалять или добавлять в любых местах практически независимо друг от друга. По сути, программу можно разделить таким образом, что она даже не поймет, что управляется с помощью Spring Java. Кроме того, данный скриптовый язык программирования значительно упрощает модульное тестирование, так как элемент, разработанный для контента IoC, достаточно просто инжектировать на ложные взаимосвязи и тем самим проверить функциональность и правильность его описания.
Spring Java также заметно упрощает инициализацию и подстройку элементов программы, то есть вы можете легко и без проблем настроить приложения под себя, не делая при этом глобальных перенастроек с основном коде Spring.
Сегодня можно найти по Java Spring учебники в огромном количестве и на различных языках (английском, русском и т. д). Поэтому осилить «Джаву» вы можете и самостоятельно, а мы в этом вам постараемся помочь!
Spring изнутри
Как построена архитектура «Джава спринг» изнутри, наверное, знает далеко не каждый. Поэтому давайте рассмотрим более детально эту конструкцию:
Spring: начало
Если вы только решили начать знакомиться с программированием на «Джава спринг», рекомендуем начинать именно с Java ee Spring (фреймворк). Это один из простейших методов с открытым исходным кодом для данной платформы «Джава». Фреймворк создает последовательную конструкцию, которую можно без проблем применить к большинству задач, что были уже ранее описаны на основе Java. Простота и прозрачность фреймворка позволит вам самостоятельно увидеть ошибки в написании.
Spring можно описать как совокупность нескольких независимых фреймворков, так и более сложных конструкций (фреймворк в фреймворке). Большинство данных структур может функционировать независимо друг от друга, однако они демонстрируют огромный объем работоспособности при совместном запуске приложения. Эти компоненты разделяются на структурные детали комплексных программ в зависимости от их предназначения:
На сегодняшний день для всех фреймворков в «Спринг» предоставляется ряд возможностей:
Необходимо понимать предназначение всех фреймворков, так как это основа Java Spring. Для начинающих рекомендуется начинать изучать все компоненты по группам и пробовать их использовать на примерах.
Как сделать простое приложение на Java Spring (фреймворк)
Конфигурацию приложения в Spring можно осуществлять несколькими способами. Одним из наиболее распространенных и достаточно простых считается вынос конфигурации в XML-файл. Этот тип традиционно используют во многих версиях Java Spring. Для начинающих рекомендуем использовать такие инструменты как java (1.5), tomcat (6), ant (1.7), eclipse (3), junit 4x.
Для того чтобы описать простую задачку в Java Spring, необходимо придерживаться такой поочередности:
На этом этапе можно сказать, что вы спешно завершили настройку сетевого окружения. Дальше следует подстроить Spring Java config:
Что же мы сделали в Spring Java? Для чайников некоторыеиз выше перечисленных пунктов будут непонятны, поэтому попробуем описать попроще:
Что такое Java Spring Security и зачем он нужен?
Spring Security позволяет авторизовать и аутентифицировать приложения. Кроме того, данный фреймворк обеспечивает безопасность корпоративных задач, которые создаются с помощью Spring Framework.
Ключевые компоненты Spring Security:
Интеграция Java
Integration Java Spring – это уникальный фреймворк, который включает в себя настройку функций, отвечающих за отправку сообщений. Кроме того, данный объект отвечает за построение действенно-ориентировочной архитектуры:
Spring Hadoop
Java Hibernate
Практически все веб-приложения не могут обойтись без хранения большого количества информации. Как правило, для решения этой проблемы используют различные специальные программы – СУБД и т. д. По структуре организации и частоте использования базы данных можно поделить на несколько подгрупп, и так получилось, что реляционные являются наиболее распространенными. Как правило, описание данных конструкций достаточно большие, и не всегда их рационально использовать.
Для преображення одного класса в другой на Java Hibernate Spring существует несколько специальных генераторов:
Преимущества использования Java Hibernate Spring:
Практика для новичков
Одним из самих простых текстовых проектов на Java Spring является написание приложения «привет». Платформа не требует дополнительной регистрации или каких-либо сложных конструкций и форм на bootstrap. Используем простой html без динамики. И пускай основная форма имеет:
Больше нам ничего не нужно. Переходим к Java Spring. Практика:
Что такое MVC, и каким образом оно связано со Spring
MVC – это собственная платформа «Спринга», которая ориентирована на запросы пользователей. В ней задан статистический вид для всех функций запросно-ориентировочных систем. Задание каждого интерфейса должно быть простым и лаконичным, чтобы пользователь по желанию мог без проблем заново имплементировать приложения. Данная платформа прокладывает прямое подключение к front-end-коду. Все интерфейсы связаны с объектом Servlet API. Благодаря этой взаимосвязи значительно упрощается программирование приложения.
К наиболее важным интерфейсам можно отнести:
К наиболее важным интерфейсам можно отнести:
Java Spring MVC (model-view-controlle) открывает перед разработчиком много дополнительных возможностей:
Основной пакет
Основной пакет является наиболее фундаментальной частью системы и обеспечивает возможность внедрения зависимостей, позволяет управлять боба-функциональностью контейнера. Основной концепцией здесь является BeanFactory, которая обеспечивает шаблон фабрики, устраняет необходимость в программной поддержке синглтонов и позволяет отделить конфигурацию и спецификацию зависимостей от фактической логики программы.
Пакет DAO предоставляет JDBC-уровень абстракции, что избавляет от необходимости делать утомительное JDBC-кодирование и разбор базы данных поставщика кодов конкретных ошибок. Кроме того, можно сделать программное, а также декларативное управление транзакциями не только для классов, реализующих интерфейсы, но и для всех ваших Pojos (простых объектов Java).
Пакет ORM обеспечивает интеграцию слоев популярных API для отображения реляционных объектов, включая JDO, Hibernate и Ibatis. Используя пакет ОРМ, вы можете применять все O/R-картографы в сочетании с другими функциями Spring-предложения.
АОП-пакет в Spring обеспечивает совместимый аспект ориентированного программирования, реализации АОП Alliance, позволяющий определить, например, метод-перехватчик и отвязать код реализации функциональных возможностей.
Применяя метаданные на уровне исходных текстов, можно включить все виды поведенческой информации в код, например NET-атрибуты.
Веб-пакет Spring обеспечивает основные веб-функции интеграции, такие как многочастная функциональность, инициализация контекстов с применением сервлетов слушателей и контекста веб-ориентированных приложений. Реализация в Spring MVC обеспечивает четкое разделение между моделью кода домена и веб-формой, что позволяет использовать все другие особенности Spring Framework для проверки.
Требования к доменным объектам
Для того чтобы приложения JPA нормально функционировало, необходимо следить за корректностью написания таких требований:
Вспомогательные группы объектов
Существует несколько дополнительных классов:
Расшифровка основных аббревиатур в Java Spring
Знакомясь с таким специфичным скриптовым методом программирования, как «Джава спринг», можно встретить разные аббревиатуры. Как правило, не на всех сайтах или в учебниках можно найти их расшифровку, поэтому давайте разберемся, что естьJava Spring. Пример:
Сегодня можно найти достаточно много полезной и интересной информации по Java Spring. Уроки, учебники, веб-семинары непременно помогут вам без проблем изучить данный скриптовый язык программирования. Если у вас возникли какие-либо проблемы с написанием приложения, пересмотрите документацию по «Спрингу», в которой авторы достаточно детально описали все требования к структуре «Джава», а также ответили на вопросы, как исправить часто совершаемые ошибки.