Spring Framework — Обзор
Spring — самая популярная среда разработки приложений для корпоративной Java. Миллионы разработчиков по всему миру используют Spring Framework для создания высокопроизводительного, легко тестируемого и многократно используемого кода.
Spring Framework — это платформа Java с открытым исходным кодом. Первоначально он был написан Родом Джонсоном и впервые выпущен под лицензией Apache 2.0 в июне 2003 года.
Весна легка, когда дело доходит до размера и прозрачности. Базовая версия Spring Framework составляет около 2 МБ.
Основные функции Spring Framework могут быть использованы при разработке любого Java-приложения, но есть расширения для создания веб-приложений поверх платформы Java EE. Платформа Spring предназначена для упрощения использования J2EE-разработки и продвижения хороших методов программирования за счет использования модели программирования на основе POJO.
Преимущества использования Spring Framework
Ниже приведен список немногих преимуществ использования Spring Framework —
-
Spring позволяет разработчикам разрабатывать приложения корпоративного класса с использованием POJO. Преимущество использования только POJO состоит в том, что вам не нужен продукт EJB-контейнера, такой как сервер приложений, но у вас есть возможность использовать только надежный контейнер сервлета, такой как Tomcat, или какой-либо коммерческий продукт.
-
Весна организована по модульному принципу. Несмотря на то, что количество пакетов и классов существенно, вам нужно беспокоиться только о тех, которые вам нужны, и игнорировать все остальное.
-
Spring не изобретает колесо, вместо этого он действительно использует некоторые из существующих технологий, таких как несколько платформ ORM, каркасы журналирования, таймеры JEE, Quartz и JDK и другие технологии представления.
-
Тестирование приложения, написанного на Spring, очень просто, потому что в эту среду перемещен код, зависящий от среды. Кроме того, благодаря использованию JavaBeanstyle POJO становится проще использовать внедрение зависимостей для ввода тестовых данных.
-
Веб-фреймворк Spring — это хорошо спроектированный веб-MVC-фреймворк, который предоставляет отличную альтернативу веб-фреймворкам, таким как Struts или другим чрезмерно спроектированным или менее популярным веб-фреймворкам.
-
Spring предоставляет удобный API-интерфейс для преобразования специфичных для технологии исключений (например, JDBC, Hibernate или JDO) в согласованные, непроверенные исключения.
-
Легкие контейнеры IoC имеют тенденцию быть легкими, особенно по сравнению, например, с контейнерами EJB. Это полезно для разработки и развертывания приложений на компьютерах с ограниченными памятью и ресурсами ЦП.
-
Spring предоставляет согласованный интерфейс управления транзакциями, который может масштабироваться до локальной транзакции (например, с использованием одной базы данных) и масштабироваться до глобальных транзакций (например, с использованием JTA).
Spring позволяет разработчикам разрабатывать приложения корпоративного класса с использованием POJO. Преимущество использования только POJO состоит в том, что вам не нужен продукт EJB-контейнера, такой как сервер приложений, но у вас есть возможность использовать только надежный контейнер сервлета, такой как Tomcat, или какой-либо коммерческий продукт.
Весна организована по модульному принципу. Несмотря на то, что количество пакетов и классов существенно, вам нужно беспокоиться только о тех, которые вам нужны, и игнорировать все остальное.
Spring не изобретает колесо, вместо этого он действительно использует некоторые из существующих технологий, таких как несколько платформ ORM, каркасы журналирования, таймеры JEE, Quartz и JDK и другие технологии представления.
Тестирование приложения, написанного на Spring, очень просто, потому что в эту среду перемещен код, зависящий от среды. Кроме того, благодаря использованию JavaBeanstyle POJO становится проще использовать внедрение зависимостей для ввода тестовых данных.
Веб-фреймворк Spring — это хорошо спроектированный веб-MVC-фреймворк, который предоставляет отличную альтернативу веб-фреймворкам, таким как Struts или другим чрезмерно спроектированным или менее популярным веб-фреймворкам.
Spring предоставляет удобный API-интерфейс для преобразования специфичных для технологии исключений (например, JDBC, Hibernate или JDO) в согласованные, непроверенные исключения.
Легкие контейнеры IoC имеют тенденцию быть легкими, особенно по сравнению, например, с контейнерами EJB. Это полезно для разработки и развертывания приложений на компьютерах с ограниченными памятью и ресурсами ЦП.
Spring предоставляет согласованный интерфейс управления транзакциями, который может масштабироваться до локальной транзакции (например, с использованием одной базы данных) и масштабироваться до глобальных транзакций (например, с использованием JTA).
Инъекция зависимостей (DI)
Технология, с которой Spring больше всего ассоциируется, — это разновидность Inversion of Control, основанная на Dependency Injection (DI) . Инверсия контроля (IoC) является общей концепцией, и она может быть выражена многими различными способами. Внедрение зависимостей является лишь одним конкретным примером инверсии контроля.
При написании сложного Java-приложения классы приложения должны быть как можно более независимыми от других Java-классов, чтобы увеличить возможность повторного использования этих классов и тестировать их независимо от других классов во время модульного тестирования. Инъекция зависимостей помогает склеивать эти классы и в то же время сохранять их независимость.
Что такое внедрение зависимости? Давайте посмотрим на эти два слова отдельно. Здесь часть зависимости переводится в ассоциацию между двумя классами. Например, класс A зависит от класса B. Теперь давайте посмотрим на вторую часть — инъекцию. Все это означает, что класс B будет введен в класс A IoC.
Внедрение зависимостей может происходить путем передачи параметров в конструктор или пост-конструированием с использованием методов установки. Поскольку Dependency Injection является сердцем Spring Framework, мы объясним эту концепцию в отдельной главе с соответствующим примером.
Аспектно-ориентированное программирование (АОП)
Одним из ключевых компонентов Spring является структура аспектно-ориентированного программирования (AOP) . Функции, охватывающие несколько точек приложения, называются сквозными задачами, и эти сквозные задачи концептуально отделены от бизнес-логики приложения. Существуют различные общие хорошие примеры аспектов, включая ведение журнала, декларативные транзакции, безопасность, кэширование и т. Д.
Ключевой единицей модульности в ООП является класс, тогда как в АОП единицей модульности является аспект. DI помогает вам отделить ваши прикладные объекты друг от друга, в то время как AOP помогает вам отделить сквозные проблемы от объектов, на которые они влияют.
Модуль AOP Spring Framework предоставляет реализацию аспектно-ориентированного программирования, позволяющую вам определять методы-перехватчики и указатели, чтобы четко отделить код, который реализует функциональность, которая должна быть отделена. Мы обсудим больше о концепции Spring AOP в отдельной главе.
Spring Framework — Архитектура
Spring потенциально может быть универсальным магазином для всех ваших корпоративных приложений. Однако Spring является модульным, позволяя вам выбирать, какие модули вам подходят, без необходимости вносить остальные. В следующем разделе приведены сведения обо всех модулях, доступных в Spring Framework.
Spring Framework предоставляет около 20 модулей, которые можно использовать в зависимости от требований приложения.
Основной контейнер
Базовый контейнер состоит из модулей Core, Beans, Context и Expression Language, подробности которых следующие:
-
Модуль Core обеспечивает основные части платформы, включая функции IoC и Dependency Injection.
-
Модуль Bean предоставляет BeanFactory, которая представляет собой сложную реализацию фабричного шаблона.
-
Модуль Context основан на прочной основе, предоставляемой модулями Core и Beans, и является средой для доступа к любым объектам, определенным и настроенным. Интерфейс ApplicationContext является координационным центром модуля Context.
-
Модуль SpEL предоставляет мощный язык выражений для запросов и манипулирования графом объектов во время выполнения.
Модуль Core обеспечивает основные части платформы, включая функции IoC и Dependency Injection.
Модуль Bean предоставляет BeanFactory, которая представляет собой сложную реализацию фабричного шаблона.
Модуль Context основан на прочной основе, предоставляемой модулями Core и Beans, и является средой для доступа к любым объектам, определенным и настроенным. Интерфейс ApplicationContext является координационным центром модуля Context.
Модуль SpEL предоставляет мощный язык выражений для запросов и манипулирования графом объектов во время выполнения.
Доступ к данным / интеграция
Уровень доступа к данным / интеграции состоит из модулей JDBC, ORM, OXM, JMS и Transaction, подробности которых следующие:
-
Модуль JDBC предоставляет уровень абстракции JDBC, который устраняет необходимость в утомительном кодировании, связанном с JDBC.
-
Модуль ORM предоставляет слои интеграции для популярных API объектно-реляционного отображения, включая JPA, JDO, Hibernate и iBatis.
-
Модуль OXM предоставляет уровень абстракции, который поддерживает реализации отображения объектов / XML для JAXB, Castor, XMLBeans, JiBX и XStream.
-
Модуль JMS Java Messaging Service содержит функции для создания и потребления сообщений.
-
Модуль Transaction поддерживает программное и декларативное управление транзакциями для классов, которые реализуют специальные интерфейсы, и для всех ваших POJO.
Модуль JDBC предоставляет уровень абстракции JDBC, который устраняет необходимость в утомительном кодировании, связанном с JDBC.
Модуль ORM предоставляет слои интеграции для популярных API объектно-реляционного отображения, включая JPA, JDO, Hibernate и iBatis.
Модуль OXM предоставляет уровень абстракции, который поддерживает реализации отображения объектов / XML для JAXB, Castor, XMLBeans, JiBX и XStream.
Модуль JMS Java Messaging Service содержит функции для создания и потребления сообщений.
Модуль Transaction поддерживает программное и декларативное управление транзакциями для классов, которые реализуют специальные интерфейсы, и для всех ваших POJO.
Web
Веб-слой состоит из модулей Web, Web-MVC, Web-Socket и Web-Portlet, подробности которых приведены ниже:
-
Веб- модуль обеспечивает базовые функции веб-интеграции, такие как функция многоэтапной загрузки файлов и инициализация контейнера IoC с использованием прослушивателей сервлетов и контекста веб-ориентированного приложения.
-
Модуль Web-MVC содержит реализацию Spring-Model-View-Controller (MVC) для веб-приложений.
-
Модуль Web-Socket обеспечивает поддержку двусторонней связи на основе WebSocket между клиентом и сервером в веб-приложениях.
-
Модуль Web- портлета предоставляет реализацию MVC для использования в среде портлета и отражает функциональность модуля Web-Servlet.
Веб- модуль обеспечивает базовые функции веб-интеграции, такие как функция многоэтапной загрузки файлов и инициализация контейнера IoC с использованием прослушивателей сервлетов и контекста веб-ориентированного приложения.
Модуль Web-MVC содержит реализацию Spring-Model-View-Controller (MVC) для веб-приложений.
Модуль Web-Socket обеспечивает поддержку двусторонней связи на основе WebSocket между клиентом и сервером в веб-приложениях.
Модуль Web- портлета предоставляет реализацию MVC для использования в среде портлета и отражает функциональность модуля Web-Servlet.
Разнообразный
Есть несколько других важных модулей, таких как AOP, Аспекты, Инструментарий, Веб и Тестовые модули, детали которых следующие:
-
Модуль AOP обеспечивает реализацию аспектно-ориентированного программирования, позволяющую вам определять методы-перехватчики и указатели, чтобы четко отделить код, который реализует функциональность, которая должна быть отделена.
-
Модуль « Аспекты » обеспечивает интеграцию с AspectJ, который снова является мощной и зрелой средой AOP.
-
Модуль Instrumentation обеспечивает поддержку инструментария класса и реализации загрузчика классов для использования на определенных серверах приложений.
-
Модуль обмена сообщениями обеспечивает поддержку STOMP в качестве суб-протокола WebSocket для использования в приложениях. Он также поддерживает модель программирования аннотаций для маршрутизации и обработки сообщений STOMP от клиентов WebSocket.
-
Модуль Test поддерживает тестирование компонентов Spring с помощью каркасов JUnit или TestNG.
Модуль AOP обеспечивает реализацию аспектно-ориентированного программирования, позволяющую вам определять методы-перехватчики и указатели, чтобы четко отделить код, который реализует функциональность, которая должна быть отделена.
Модуль « Аспекты » обеспечивает интеграцию с AspectJ, который снова является мощной и зрелой средой AOP.
Модуль Instrumentation обеспечивает поддержку инструментария класса и реализации загрузчика классов для использования на определенных серверах приложений.
Модуль обмена сообщениями обеспечивает поддержку STOMP в качестве суб-протокола WebSocket для использования в приложениях. Он также поддерживает модель программирования аннотаций для маршрутизации и обработки сообщений STOMP от клиентов WebSocket.
Модуль Test поддерживает тестирование компонентов Spring с помощью каркасов JUnit или TestNG.
Весна — Настройка среды
В этой главе вы узнаете, как подготовить среду разработки, чтобы начать работу с Spring Framework. Он также научит вас настраивать JDK, Tomcat и Eclipse на вашем компьютере до того, как вы настроите Spring Framework —
Шаг 1 — Настройка Java Development Kit (JDK)
Вы можете скачать последнюю версию SDK с сайта Oracle на Java — Java SE Downloads. В загруженных файлах вы найдете инструкции по установке JDK, следуйте инструкциям по установке и настройке. Наконец, установите переменные окружения PATH и JAVA_HOME, чтобы они ссылались на каталог, содержащий java и javac, обычно java_install_dir / bin и java_install_dir соответственно.
Если вы работаете в Windows и установили JDK в C: \ jdk1.6.0_15, вам потребуется поместить следующую строку в ваш файл C: \ autoexec.bat.
set PATH=C:\jdk1.6.0_15\bin;%PATH% set JAVA_HOME=C:\jdk1.6.0_15
Кроме того, в Windows NT / 2000 / XP вам нужно будет щелкнуть правой кнопкой мыши Мой компьютер, выбрать Свойства → Дополнительно → Переменные среды. Затем вам нужно будет обновить значение PATH и нажать кнопку ОК.
В Unix (Solaris, Linux и т. Д.), Если SDK установлен в /usr/local/jdk1.6.0_15 и вы используете оболочку C, вам нужно будет добавить следующее в ваш файл .cshrc.
setenv PATH /usr/local/jdk1.6.0_15/bin:$PATH setenv JAVA_HOME /usr/local/jdk1.6.0_15
В качестве альтернативы, если вы используете интегрированную среду разработки (IDE), такую как Borland JBuilder, Eclipse, IntelliJ IDEA или Sun ONE Studio, вам придется скомпилировать и запустить простую программу, чтобы подтвердить, что IDE знает, где вы установили Java. В противном случае вам придется выполнить правильную настройку, как указано в документе IDE.
Шаг 2 — Установите Apache Common Logging API
Вы можете загрузить последнюю версию API регистрации Apache Commons с https://commons.apache.org/logging/ . После загрузки установки распакуйте бинарный дистрибутив в удобное место. Например, в C: \ commons-logging-1.1.1 в Windows или /usr/local/commons-logging-1.1.1 в Linux / Unix. В этом каталоге будут находиться следующие jar-файлы, другие сопроводительные документы и т. Д.
Убедитесь, что вы правильно установили переменную CLASSPATH в этом каталоге, иначе вы столкнетесь с проблемой при запуске приложения.
Шаг 3 — Настройка Eclipse IDE
Все примеры в этом руководстве написаны с использованием Eclipse IDE. Поэтому мы рекомендуем вам установить на вашем компьютере последнюю версию Eclipse.
Чтобы установить Eclipse IDE, загрузите последние двоичные файлы Eclipse со страницы https://www.eclipse.org/downloads/ . После загрузки установки распакуйте бинарный дистрибутив в удобное место. Например, в C: \ eclipse в Windows или / usr / local / eclipse в Linux / Unix и, наконец, установите переменную PATH соответствующим образом.
Eclipse можно запустить, выполнив следующие команды на компьютере с Windows, или вы можете просто дважды щелкнуть файл eclipse.exe
%C:\eclipse\eclipse.exe
Eclipse можно запустить, выполнив следующие команды на компьютере Unix (Solaris, Linux и т. Д.):
$/usr/local/eclipse/eclipse
После успешного запуска, если все в порядке, он должен отобразить следующий результат —
Шаг 4 — Настройка библиотек Spring Framework
Теперь, если все в порядке, вы можете приступить к настройке среды Spring. Ниже приведены простые шаги для загрузки и установки фреймворка на вашем компьютере.
-
Выберите, хотите ли вы установить Spring в Windows или Unix, а затем перейдите к следующему шагу, чтобы загрузить .zip-файл для Windows и .tz-файл для Unix.
-
Загрузите последнюю версию бинарных файлов среды Spring с https://repo.spring.io/release/org/springframework/spring .
-
На момент разработки этого руководства на компьютере с Windows была загружена spring-framework-4.1.6.RELEASE-dist.zip . После того, как загруженный файл был распакован, он дает следующую структуру каталогов внутри E: \ spring.
Выберите, хотите ли вы установить Spring в Windows или Unix, а затем перейдите к следующему шагу, чтобы загрузить .zip-файл для Windows и .tz-файл для Unix.
Загрузите последнюю версию бинарных файлов среды Spring с https://repo.spring.io/release/org/springframework/spring .
На момент разработки этого руководства на компьютере с Windows была загружена spring-framework-4.1.6.RELEASE-dist.zip . После того, как загруженный файл был распакован, он дает следующую структуру каталогов внутри E: \ spring.
Вы найдете все библиотеки Spring в каталоге E: \ spring \ libs . Убедитесь, что вы правильно установили переменную CLASSPATH в этом каталоге, иначе вы столкнетесь с проблемой при запуске приложения. Если вы используете Eclipse, то не обязательно устанавливать CLASSPATH, потому что все настройки будут выполнены через Eclipse.
Как только вы закончите с этим последним шагом, вы будете готовы перейти к первому весеннему примеру в следующей главе.
Весна — пример Hello World
Давайте начнем актуальное программирование с Spring Framework. Прежде чем вы начнете писать свой первый пример с использованием Spring Framework, вы должны убедиться, что вы правильно настроили среду Spring, как описано в главе « Настройка среды Spring» . Мы также предполагаем, что у вас есть кое-какие практические знания по Eclipse IDE.
Теперь давайте приступим к написанию простого Spring-приложения, которое напечатает «Hello World!» или любое другое сообщение на основе конфигурации, выполненной в файле конфигурации Spring Beans.
Шаг 1 — Создать проект Java
Первым шагом является создание простого Java-проекта с использованием Eclipse IDE. Выберите « Файл» → «Создать» → «Проект» и, наконец, выберите «Мастер Java-проектов» из списка. Теперь назовите ваш проект как HelloSpring, используя окно мастера следующим образом:
Как только ваш проект будет успешно создан, вы увидите следующее содержимое в Project Explorer —
Шаг 2 — Добавить необходимые библиотеки
В качестве второго шага давайте добавим в наш проект Spring Framework и общие библиотеки API ведения логов. Для этого щелкните правой кнопкой мыши на имени вашего проекта HelloSpring и затем следуйте следующей опции, доступной в контекстном меню — Путь сборки → Настроить путь сборки, чтобы отобразить окно Путь сборки Java следующим образом —
Теперь используйте кнопку « Добавить внешние JAR» , доступную на вкладке « Библиотеки », чтобы добавить следующие основные JAR из директорий установки Spring Framework и Common Logging —
-
Обще-каротаж 1.1.1
-
весна-АОП-4.1.6.RELEASE
-
весна-аспекты, 4.1.6.RELEASE
-
весна-бобы-4.1.6.RELEASE
-
пружинный контекстно-4.1.6.RELEASE
-
весна-контекст-поддержка-4.1.6.RELEASE
-
весна-ядро-4.1.6.RELEASE
-
весна-выражение-4.1.6.RELEASE
-
весна-инструмент-4.1.6.RELEASE
-
весна-приборостроение-4.1.6.RELEASE кот
-
весна-4.1.6.RELEASE JDBC
-
весна-JMS-4.1.6.RELEASE
-
весна-сообщения-4.1.6.RELEASE
-
весна-ОРМ-4.1.6.RELEASE
-
весна-ОХМ 4.1.6.RELEASE
-
весна-тест-4.1.6.RELEASE
-
весна-ТХ-4.1.6.RELEASE
-
весна-веб-4.1.6.RELEASE
-
весна-webmvc-4.1.6.RELEASE
-
весна-webmvc-портлет-4.1.6.RELEASE
-
весна-WebSocket-4.1.6.RELEASE
Обще-каротаж 1.1.1
весна-АОП-4.1.6.RELEASE
весна-аспекты, 4.1.6.RELEASE
весна-бобы-4.1.6.RELEASE
пружинный контекстно-4.1.6.RELEASE
весна-контекст-поддержка-4.1.6.RELEASE
весна-ядро-4.1.6.RELEASE
весна-выражение-4.1.6.RELEASE
весна-инструмент-4.1.6.RELEASE
весна-приборостроение-4.1.6.RELEASE кот
весна-4.1.6.RELEASE JDBC
весна-JMS-4.1.6.RELEASE
весна-сообщения-4.1.6.RELEASE
весна-ОРМ-4.1.6.RELEASE
весна-ОХМ 4.1.6.RELEASE
весна-тест-4.1.6.RELEASE
весна-ТХ-4.1.6.RELEASE
весна-веб-4.1.6.RELEASE
весна-webmvc-4.1.6.RELEASE
весна-webmvc-портлет-4.1.6.RELEASE
весна-WebSocket-4.1.6.RELEASE
Шаг 3 — Создание исходных файлов
Теперь давайте создадим реальные исходные файлы в рамках проекта HelloSpring . Сначала нам нужно создать пакет с именем com.tutorialspoint . Для этого щелкните правой кнопкой мыши на src в разделе проводника пакетов и выберите опцию — Создать → Пакет .
Далее мы создадим файлы HelloWorld.java и MainApp.java в пакете com.tutorialspoint.
Вот содержимое файла HelloWorld.java —
package com.tutorialspoint; public class HelloWorld { private String message; public void setMessage(String message){ this.message = message; } public void getMessage(){ System.out.println("Your Message : " + message); } }
Ниже приводится содержание второго файла MainApp.java —
package com.tutorialspoint; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class MainApp { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml"); HelloWorld obj = (HelloWorld) context.getBean("helloWorld"); obj.getMessage(); } }
Следующие два важных момента следует отметить о основной программе —
-
Первым шагом является создание контекста приложения, в котором мы использовали фреймворк API ClassPathXmlApplicationContext () . Этот API загружает файл конфигурации bean-компонентов и, в конечном итоге, на основе предоставленного API-интерфейса обеспечивает создание и инициализацию всех объектов, то есть bean-компонентов, указанных в файле конфигурации.
-
Второй шаг используется для получения необходимого компонента с помощью метода getBean () созданного контекста. Этот метод использует идентификатор компонента для возврата универсального объекта, который в конечном итоге может быть приведен к реальному объекту. Если у вас есть объект, вы можете использовать этот объект для вызова любого метода класса.
Первым шагом является создание контекста приложения, в котором мы использовали фреймворк API ClassPathXmlApplicationContext () . Этот API загружает файл конфигурации bean-компонентов и, в конечном итоге, на основе предоставленного API-интерфейса обеспечивает создание и инициализацию всех объектов, то есть bean-компонентов, указанных в файле конфигурации.
Второй шаг используется для получения необходимого компонента с помощью метода getBean () созданного контекста. Этот метод использует идентификатор компонента для возврата универсального объекта, который в конечном итоге может быть приведен к реальному объекту. Если у вас есть объект, вы можете использовать этот объект для вызова любого метода класса.
Шаг 4 — Создайте файл конфигурации бина
Вам необходимо создать файл конфигурации бина, который является XML-файлом и действует как цемент, который склеивает бины, то есть классы вместе. Этот файл должен быть создан в каталоге src, как показано на следующем снимке экрана —
Обычно разработчики называют этот файл как Beans.xml , но вы не можете выбирать любое имя, которое вам нравится. Вы должны убедиться, что этот файл доступен в CLASSPATH и использовать то же имя в основном приложении при создании контекста приложения, как показано в файле MainApp.java.
Beans.xml используется для назначения уникальных идентификаторов различным bean-компонентам и для управления созданием объектов с различными значениями, не затрагивая ни один из исходных файлов Spring. Например, используя следующий файл, вы можете передать любое значение переменной «message» и напечатать разные значения сообщения, не затрагивая файлы HelloWorld.java и MainApp.java. Давайте посмотрим, как это работает —
<?xml version = "1.0" encoding = "UTF-8"?> <beans xmlns = "http://www.springframework.org/schema/beans" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation = "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <bean id = "helloWorld" class = "com.tutorialspoint.HelloWorld"> <property name = "message" value = "Hello World!"/> </bean> </beans>
Когда приложение Spring загружается в память, Framework использует указанный выше файл конфигурации для создания всех определенных bean-компонентов и присваивает им уникальный идентификатор, определенный в теге <bean> . Вы можете использовать тег <property> для передачи значений различных переменных, используемых во время создания объекта.
Шаг 5 — Запуск программы
Как только вы закончили создавать файлы конфигурации исходного кода и bean-компонентов, вы готовы к этому шагу, который заключается в компиляции и запуске вашей программы. Для этого сохраните активную вкладку файла MainApp.Java и используйте либо опцию « Выполнить», доступную в Eclipse IDE, либо используйте Ctrl + F11 для компиляции и запуска приложения MainApp . Если с вашим приложением все в порядке, в консоли Eclipse IDE будет напечатано следующее сообщение:
Your Message : Hello World!
Поздравляем, вы успешно создали свое первое приложение Spring. Вы можете увидеть гибкость вышеупомянутого приложения Spring, изменив значение свойства «message» и оставив оба исходных файла без изменений.
Весна — Контейнеры IoC
Контейнер Spring является ядром Spring Framework. Контейнер будет создавать объекты, связывать их вместе, настраивать их и управлять их полным жизненным циклом от создания до разрушения. Контейнер Spring использует DI для управления компонентами, составляющими приложение. Эти объекты называются Spring Beans, которые мы обсудим в следующей главе.
Контейнер получает инструкции о том, какие объекты создавать, настраивать и собирать, читая предоставленные метаданные конфигурации. Метаданные конфигурации могут быть представлены в виде XML, аннотаций Java или кода Java. Следующая диаграмма представляет высокоуровневое представление о том, как работает Spring. Контейнер Spring IoC использует классы Java POJO и метаданные конфигурации для создания полностью сконфигурированной и исполняемой системы или приложения.
Spring предоставляет следующие два различных типа контейнеров.
Sr.No. | Контейнер и описание |
---|---|
1 | Spring BeanFactory Контейнер
Это самый простой контейнер, обеспечивающий базовую поддержку DI и определяемый интерфейсом org.springframework.beans.factory.BeanFactory . BeanFactory и связанные интерфейсы, такие как BeanFactoryAware, InitializingBean, DisposableBean, по-прежнему присутствуют в Spring с целью обеспечения обратной совместимости с большим количеством сторонних сред, интегрируемых с Spring. |
2 | Spring ApplicationContext Container
Этот контейнер добавляет больше специфических для предприятия функций, таких как возможность разрешать текстовые сообщения из файла свойств и возможность публиковать события приложения для заинтересованных слушателей событий. Этот контейнер определяется интерфейсом org.springframework.context.ApplicationContext . |
Это самый простой контейнер, обеспечивающий базовую поддержку DI и определяемый интерфейсом org.springframework.beans.factory.BeanFactory . BeanFactory и связанные интерфейсы, такие как BeanFactoryAware, InitializingBean, DisposableBean, по-прежнему присутствуют в Spring с целью обеспечения обратной совместимости с большим количеством сторонних сред, интегрируемых с Spring.
Этот контейнер добавляет больше специфических для предприятия функций, таких как возможность разрешать текстовые сообщения из файла свойств и возможность публиковать события приложения для заинтересованных слушателей событий. Этот контейнер определяется интерфейсом org.springframework.context.ApplicationContext .
Контейнер ApplicationContext включает в себя все функциональные возможности контейнера BeanFactory , поэтому его обычно рекомендуется использовать поверх BeanFactory . BeanFactory по-прежнему можно использовать для легких приложений, таких как мобильные устройства или приложения на основе апплетов, где объем и скорость данных значительны.
Весна — Определение бобов
Объекты, которые образуют основу вашего приложения и управляются контейнером Spring IoC, называются bean-компонентами . Бин — это объект, который создается, собирается и иным образом управляется контейнером Spring IoC. Эти компоненты создаются с помощью метаданных конфигурации, которые вы предоставляете контейнеру. Например, в форме определений XML <bean />, которые вы уже видели в предыдущих главах.
Определение компонента содержит информацию, называемую метаданными конфигурации , которая необходима контейнеру, чтобы знать следующее:
- Как создать боб
- Подробности жизненного цикла Бина
- Зависимости Бина
Все приведенные выше метаданные конфигурации преобразуются в набор следующих свойств, которые составляют каждое определение компонента.
Sr.No. | Свойства и описание |
---|---|
1 |
учебный класс Этот атрибут является обязательным и определяет класс компонента, который будет использоваться для создания компонента. |
2 |
название Этот атрибут уникальным образом определяет идентификатор компонента. В метаданных конфигурации на основе XML вы используете атрибуты id и / или name для указания идентификатора (ов) компонента. |
3 |
объем Этот атрибут задает область действия объектов, созданных из определенного определения компонента, и он будет обсуждаться в главе об областях применения компонента. |
4 |
Конструктор-Arg Это используется для внедрения зависимостей и будет обсуждаться в последующих главах. |
5 |
свойства Это используется для внедрения зависимостей и будет обсуждаться в последующих главах. |
6 |
режим автопроводки Это используется для внедрения зависимостей и будет обсуждаться в последующих главах. |
7 |
режим ленивой инициализации Инициализированный ленивый bean-компонент сообщает контейнеру IoC о создании экземпляра bean-компонента при первом запросе, а не при запуске. |
8 |
метод инициализации Обратный вызов, вызываемый сразу после того, как контейнер установил все необходимые свойства в bean-компоненте. Это будет обсуждаться в главе о жизненном цикле бобов. |
9 |
метод уничтожения Обратный вызов, который нужно использовать, когда контейнер, содержащий бин, уничтожен. Это будет обсуждаться в главе о жизненном цикле бобов. |
учебный класс
Этот атрибут является обязательным и определяет класс компонента, который будет использоваться для создания компонента.
название
Этот атрибут уникальным образом определяет идентификатор компонента. В метаданных конфигурации на основе XML вы используете атрибуты id и / или name для указания идентификатора (ов) компонента.
объем
Этот атрибут задает область действия объектов, созданных из определенного определения компонента, и он будет обсуждаться в главе об областях применения компонента.
Конструктор-Arg
Это используется для внедрения зависимостей и будет обсуждаться в последующих главах.
свойства
Это используется для внедрения зависимостей и будет обсуждаться в последующих главах.
режим автопроводки
Это используется для внедрения зависимостей и будет обсуждаться в последующих главах.
режим ленивой инициализации
Инициализированный ленивый bean-компонент сообщает контейнеру IoC о создании экземпляра bean-компонента при первом запросе, а не при запуске.
метод инициализации
Обратный вызов, вызываемый сразу после того, как контейнер установил все необходимые свойства в bean-компоненте. Это будет обсуждаться в главе о жизненном цикле бобов.
метод уничтожения
Обратный вызов, который нужно использовать, когда контейнер, содержащий бин, уничтожен. Это будет обсуждаться в главе о жизненном цикле бобов.
Метаданные конфигурации Spring
Контейнер Spring IoC полностью отделен от формата, в котором эти метаданные конфигурации фактически записаны. Ниже приведены три важных метода предоставления метаданных конфигурации в Spring-контейнер.
- XML-файл конфигурации.
- Конфигурация на основе аннотаций
- Конфигурация на основе Java
Вы уже видели, как метаданные конфигурации на основе XML предоставляются контейнеру, но давайте рассмотрим другой пример файла конфигурации на основе XML с различными определениями bean-компонентов, включая отложенную инициализацию, метод инициализации и метод уничтожения —
<?xml version = "1.0" encoding = "UTF-8"?> <beans xmlns = "http://www.springframework.org/schema/beans" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation = "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <!-- A simple bean definition --> <bean id = "..." class = "..."> <!-- collaborators and configuration for this bean go here --> </bean> <!-- A bean definition with lazy init set on --> <bean id = "..." class = "..." lazy-init = "true"> <!-- collaborators and configuration for this bean go here --> </bean> <!-- A bean definition with initialization method --> <bean id = "..." class = "..." init-method = "..."> <!-- collaborators and configuration for this bean go here --> </bean> <!-- A bean definition with destruction method --> <bean id = "..." class = "..." destroy-method = "..."> <!-- collaborators and configuration for this bean go here --> </bean> <!-- more bean definitions go here --> </beans>
Вы можете проверить Spring Hello World Example, чтобы понять, как определять, настраивать и создавать Spring Beans.
Мы обсудим конфигурацию на основе аннотаций в отдельной главе. Это намеренно обсуждается в отдельной главе, так как мы хотим, чтобы вы поняли несколько других важных концепций Spring, прежде чем начинать программировать с Spring Dependency Injection с аннотациями.
Весна — Объем бобов
При определении <bean> у вас есть возможность объявить область действия для этого bean. Например, чтобы заставить Spring создавать новый экземпляр компонента каждый раз, когда он необходим, вы должны объявить атрибут области действия компонента как прототип . Точно так же, если вы хотите, чтобы Spring возвращал один и тот же экземпляр компонента каждый раз, когда он необходим, вы должны объявить атрибут области действия компонента как одноэлементный .
Spring Framework поддерживает следующие пять областей, три из которых доступны только при использовании веб-приложения ApplicationContext.
Sr.No. | Область применения и описание |
---|---|
1 |
одиночка Это ограничивает определение компонента одним экземпляром для каждого контейнера IoC Spring (по умолчанию). |
2 |
прототип Это ограничивает определение единственного бина любым количеством экземпляров объекта. |
3 |
запрос Это ограничивает определение bean-компонента до HTTP-запроса. Действителен только в контексте веб-приложения Spring ApplicationContext. |
4 |
сессия Это ограничивает определение компонента для сеанса HTTP. Действителен только в контексте веб-приложения Spring ApplicationContext. |
5 |
глобальный сеанс Это определяет определение bean-компонента для глобального сеанса HTTP. Действителен только в контексте веб-приложения Spring ApplicationContext. |
одиночка
Это ограничивает определение компонента одним экземпляром для каждого контейнера IoC Spring (по умолчанию).
прототип
Это ограничивает определение единственного бина любым количеством экземпляров объекта.
запрос
Это ограничивает определение bean-компонента до HTTP-запроса. Действителен только в контексте веб-приложения Spring ApplicationContext.
сессия
глобальный сеанс
Это определяет определение bean-компонента для глобального сеанса HTTP. Действителен только в контексте веб-приложения Spring ApplicationContext.
В этой главе мы обсудим первые две области, а остальные три — при обсуждении веб-приложения Spring ApplicationContext с поддержкой веб-интерфейса.
Одиночная сфера
Если для области задано одноэлементное значение, контейнер Spring IoC создает ровно один экземпляр объекта, определенный этим определением компонента. Этот единственный экземпляр хранится в кэше таких одноэлементных компонентов, и все последующие запросы и ссылки для этого именованного компонента возвращают кешированный объект.
Область по умолчанию всегда одноэлементная. Однако, когда вам нужен один и только один экземпляр компонента, вы можете установить для свойства scope значение singleton в файле конфигурации компонента, как показано в следующем фрагменте кода:
<!-- A bean definition with singleton scope --> <bean id = "..." class = "..." scope = "singleton"> <!-- collaborators and configuration for this bean go here --> </bean>
пример
Давайте создадим рабочую среду Eclipse и предпримем следующие шаги для создания приложения Spring:
меры | Описание |
---|---|
1 | Создайте проект с именем SpringExample и создайте пакет com.tutorialspoint в папке src в созданном проекте. |
2 | Добавьте необходимые библиотеки Spring с помощью параметра « Добавить внешние JAR-файлы», как описано в главе « Пример Hello World» . |
3 | Создайте классы Java HelloWorld и MainApp в пакете com.tutorialspoint . |
4 | Создайте файл конфигурации Beans Beans.xml в папке src . |
5 | Последний шаг — создать содержимое всех файлов Java и файла конфигурации Bean и запустить приложение, как описано ниже. |
Вот содержимое файла HelloWorld.java —
package com.tutorialspoint; public class HelloWorld { private String message; public void setMessage(String message){ this.message = message; } public void getMessage(){ System.out.println("Your Message : " + message); } }
Ниже приводится содержание файла MainApp.java —
package com.tutorialspoint; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class MainApp { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml"); HelloWorld objA = (HelloWorld) context.getBean("helloWorld"); objA.setMessage("I'm object A"); objA.getMessage(); HelloWorld objB = (HelloWorld) context.getBean("helloWorld"); objB.getMessage(); } }
Ниже приведен файл конфигурации Beans.xml, необходимый для одноэлементной области действия.
<?xml version = "1.0" encoding = "UTF-8"?> <beans xmlns = "http://www.springframework.org/schema/beans" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation = "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <bean id = "helloWorld" class = "com.tutorialspoint.HelloWorld" scope = "singleton"> </bean> </beans>
Как только вы закончили создавать файлы конфигурации исходного кода и bean-компонента, давайте запустим приложение Если с вашим приложением все в порядке, оно напечатает следующее сообщение:
Your Message : I'm object A Your Message : I'm object A
Объем прототипа
Если для области установлен прототип, контейнер Spring IoC создает новый экземпляр объекта каждый раз, когда выполняется запрос для этого конкретного компонента. Как правило, используйте область прототипа для всех bean-компонентов с полным состоянием и одноэлементную область для bean-компонентов без состояния.
Чтобы определить область действия прототипа, вы можете установить для свойства области значение prototype в файле конфигурации компонента, как показано в следующем фрагменте кода:
<!-- A bean definition with prototype scope --> <bean id = "..." class = "..." scope = "prototype"> <!-- collaborators and configuration for this bean go here --> </bean>
пример
Давайте создадим рабочую среду Eclipse и выполните следующие шаги для создания приложения Spring:
меры | Описание |
---|---|
1 | Создайте проект с именем SpringExample и создайте пакет com.tutorialspoint в папке src в созданном проекте. |
2 | Добавьте необходимые библиотеки Spring с помощью параметра « Добавить внешние JAR-файлы», как описано в главе « Пример Hello World» . |
3 | Создайте классы Java HelloWorld и MainApp в пакете com.tutorialspoint . |
4 | Создайте файл конфигурации Beans Beans.xml в папке src . |
5 | Последний шаг — создать содержимое всех файлов Java и файла конфигурации Bean и запустить приложение, как описано ниже. |
Вот содержимое файла HelloWorld.java
package com.tutorialspoint; public class HelloWorld { private String message; public void setMessage(String message){ this.message = message; } public void getMessage(){ System.out.println("Your Message : " + message); } }
Ниже приводится содержание файла MainApp.java —
package com.tutorialspoint; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class MainApp { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml"); HelloWorld objA = (HelloWorld) context.getBean("helloWorld"); objA.setMessage("I'm object A"); objA.getMessage(); HelloWorld objB = (HelloWorld) context.getBean("helloWorld"); objB.getMessage(); } }
Ниже приведен файл конфигурации Beans.xml, необходимый для области действия прототипа.
<?xml version = "1.0" encoding = "UTF-8"?> <beans xmlns = "http://www.springframework.org/schema/beans" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation = "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <bean id = "helloWorld" class = "com.tutorialspoint.HelloWorld" scope = "prototype"> </bean> </beans>
Как только вы закончили создавать файлы конфигурации исходного кода и bean-компонента, давайте запустим приложение Если с вашим приложением все в порядке, оно напечатает следующее сообщение:
Your Message : I'm object A Your Message : null
Весна — жизненный цикл бобов
Жизненный цикл бобов Spring легко понять. Когда создается экземпляр компонента, может потребоваться выполнить некоторую инициализацию, чтобы перевести его в работоспособное состояние. Точно так же, когда боб больше не требуется и вынимается из контейнера, может потребоваться некоторая очистка.
Хотя существуют списки действий, которые происходят за кулисами между моментом создания компонента и его уничтожением, в этой главе будут обсуждаться только два важных метода обратного вызова жизненного цикла компонента, которые необходимы во время инициализации компонента и его уничтожения.
Чтобы определить настройку и демонтаж для bean-компонента, мы просто объявляем <bean-компонент> с параметрами initmethod и / или destroy-method . Атрибут init-method указывает метод, который должен вызываться в bean-компоненте сразу после его создания. Аналогично, destroymethod определяет метод, который вызывается непосредственно перед удалением компонента из контейнера.
Инициализация обратных вызовов
Интерфейс org.springframework.beans.factory.InitializingBean указывает один метод —
void afterPropertiesSet() throws Exception;
Таким образом, вы можете просто реализовать описанный выше интерфейс, а инициализацию можно выполнить внутри метода afterPropertiesSet () следующим образом:
public class ExampleBean implements InitializingBean { public void afterPropertiesSet() { // do some initialization work } }
В случае метаданных конфигурации на основе XML вы можете использовать атрибут init-method, чтобы указать имя метода, имеющего пустую подпись без аргументов. Например —
<bean id = "exampleBean" class = "examples.ExampleBean" init-method = "init"/>
Ниже приводится определение класса —
public class ExampleBean { public void init() { // do some initialization work } }
Уничтожение колбэков
Интерфейс org.springframework.beans.factory.DisposableBean указывает один метод —
void destroy() throws Exception;
Таким образом, вы можете просто реализовать описанный выше интерфейс, а завершающая работа может быть выполнена внутри метода destroy () следующим образом:
public class ExampleBean implements DisposableBean { public void destroy() { // do some destruction work } }
В случае метаданных конфигурации на основе XML вы можете использовать атрибут destroy-method, чтобы указать имя метода, имеющего пустую подпись без аргументов. Например —
<bean id = "exampleBean" class = "examples.ExampleBean" destroy-method = "destroy"/>
Ниже приводится определение класса —
public class ExampleBean { public void destroy() { // do some destruction work } }
Если вы используете IoC-контейнер Spring в среде без веб-приложений; например, в среде рабочего стола с расширенным клиентом вы регистрируете перехват выключения в JVM. Это гарантирует плавное завершение работы и вызывает соответствующие методы уничтожения для ваших одноэлементных компонентов, чтобы освободить все ресурсы.
Рекомендуется не использовать обратные вызовы InitializingBean или DisposableBean, потому что конфигурация XML дает большую гибкость с точки зрения именования вашего метода.
пример
Давайте создадим рабочую среду Eclipse и предпримем следующие шаги для создания приложения Spring:
меры | Описание |
---|---|
1 | Создайте проект с именем SpringExample и создайте пакет com.tutorialspoint в папке src в созданном проекте. |
2 | Добавьте необходимые библиотеки Spring с помощью параметра « Добавить внешние JAR-файлы», как описано в главе « Пример Hello World» . |
3 | Создайте классы Java HelloWorld и MainApp в пакете com.tutorialspoint . |
4 | Создайте файл конфигурации Beans Beans.xml в папке src . |
5 | Последний шаг — создать содержимое всех файлов Java и файла конфигурации Bean и запустить приложение, как описано ниже. |
Вот содержимое файла HelloWorld.java —
package com.tutorialspoint; public class HelloWorld { private String message; public void setMessage(String message){ this.message = message; } public void getMessage(){ System.out.println("Your Message : " + message); } public void init(){ System.out.println("Bean is going through init."); } public void destroy() { System.out.println("Bean will destroy now."); } }
Ниже приводится содержание файла MainApp.java . Здесь вам нужно зарегистрировать метод hookSdowndownStoreShutdownHook (), который объявлен в классе AbstractApplicationContext. Это обеспечит постепенное отключение и вызовет соответствующие методы уничтожения.
package com.tutorialspoint; import org.springframework.context.support.AbstractApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class MainApp { public static void main(String[] args) { AbstractApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml"); HelloWorld obj = (HelloWorld) context.getBean("helloWorld"); obj.getMessage(); context.registerShutdownHook(); } }
Ниже приведен файл конфигурации Beans.xml, необходимый для методов init и destroy:
<?xml version = "1.0" encoding = "UTF-8"?> <beans xmlns = "http://www.springframework.org/schema/beans" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation = "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <bean id = "helloWorld" class = "com.tutorialspoint.HelloWorld" init-method = "init" destroy-method = "destroy"> <property name = "message" value = "Hello World!"/> </bean> </beans>
Как только вы закончили создавать файлы конфигурации исходного кода и bean-компонента, давайте запустим приложение Если с вашим приложением все в порядке, оно напечатает следующее сообщение:
Bean is going through init. Your Message : Hello World! Bean will destroy now.
Методы инициализации и уничтожения по умолчанию
Если у вас слишком много бинов, имеющих методы инициализации и / или уничтожения с одинаковыми именами, вам не нужно объявлять метод init и метод destroy для каждого отдельного компонента. Вместо этого платформа предоставляет гибкость для настройки такой ситуации с использованием атрибутов default-init-method и default-destroy-method для элемента <beans> следующим образом:
<beans xmlns = "http://www.springframework.org/schema/beans" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation = "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd" default-init-method = "init" default-destroy-method = "destroy"> <bean id = "..." class = "..."> <!-- collaborators and configuration for this bean go here --> </bean> </beans>
Spring — Bean Post Processors
Интерфейс BeanPostProcessor определяет методы обратного вызова, которые вы можете реализовать, чтобы обеспечить собственную логику создания экземпляров, логику разрешения зависимостей и т. Д. Вы также можете реализовать некоторую настраиваемую логику после того, как контейнер Spring завершит создание, настройку и инициализацию компонента, подключив один или несколько Реализации BeanPostProcessor.
Вы можете настроить несколько интерфейсов BeanPostProcessor и управлять порядком, в котором эти интерфейсы BeanPostProcessor выполняются, установив свойство order при условии, что BeanPostProcessor реализует интерфейс Ordered .
BeanPostProcessors работают с экземплярами компонента (или объекта), что означает, что контейнер Spring IoC создает экземпляр компонента, а затем интерфейсы BeanPostProcessor выполняют свою работу.
ApplicationContext автоматически обнаруживает любые bean-компоненты, определенные с помощью реализации интерфейса BeanPostProcessor, и регистрирует эти bean-компоненты как постпроцессоры, которые затем будут соответствующим образом вызываться контейнером при создании bean-компонента.
пример
В следующих примерах показано, как писать, регистрировать и использовать BeanPostProcessors в контексте ApplicationContext.
Давайте создадим рабочую среду Eclipse и предпримем следующие шаги для создания приложения Spring:
меры | Описание |
---|---|
1 | Создайте проект с именем SpringExample и создайте пакет com.tutorialspoint в папке src в созданном проекте. |
2 | Добавьте необходимые библиотеки Spring с помощью параметра « Добавить внешние JAR-файлы», как описано в главе « Пример Hello World» . |
3 | Создайте классы Java HelloWorld , InitHelloWorld и MainApp в пакете com.tutorialspoint . |
4 | Создайте файл конфигурации Beans Beans.xml в папке src . |
5 | Последний шаг — создать содержимое всех файлов Java и файла конфигурации Bean и запустить приложение, как описано ниже. |
Вот содержимое файла HelloWorld.java —
package com.tutorialspoint; public class HelloWorld { private String message; public void setMessage(String message){ this.message = message; } public void getMessage(){ System.out.println("Your Message : " + message); } public void init(){ System.out.println("Bean is going through init."); } public void destroy(){ System.out.println("Bean will destroy now."); } }
Это очень простой пример реализации BeanPostProcessor, который печатает имя компонента до и после инициализации любого компонента. Вы можете реализовать более сложную логику до и после инициализации компонента, поскольку у вас есть доступ к объекту компонента внутри обоих методов постпроцессора.
Вот содержимое файла InitHelloWorld.java —
package com.tutorialspoint; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.beans.BeansException; public class InitHelloWorld implements BeanPostProcessor { public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("BeforeInitialization : " + beanName); return bean; // you can return any other object as well } public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("AfterInitialization : " + beanName); return bean; // you can return any other object as well } }
Ниже приводится содержание файла MainApp.java . Здесь вам нужно зарегистрировать метод hookSdowndownStoreShutdownHook (), который объявлен в классе AbstractApplicationContext. Это обеспечит постепенное отключение и вызовет соответствующие методы уничтожения.
package com.tutorialspoint; import org.springframework.context.support.AbstractApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class MainApp { public static void main(String[] args) { AbstractApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml"); HelloWorld obj = (HelloWorld) context.getBean("helloWorld"); obj.getMessage(); context.registerShutdownHook(); } }
Ниже приведен файл конфигурации Beans.xml, необходимый для методов init и destroy:
<?xml version = "1.0" encoding = "UTF-8"?> <beans xmlns = "http://www.springframework.org/schema/beans" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation = "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <bean id = "helloWorld" class = "com.tutorialspoint.HelloWorld" init-method = "init" destroy-method = "destroy"> <property name = "message" value = "Hello World!"/> </bean> <bean class = "com.tutorialspoint.InitHelloWorld" /> </beans>
Как только вы закончили создавать файлы конфигурации исходного кода и bean-компонента, давайте запустим приложение. Если с вашим приложением все в порядке, оно напечатает следующее сообщение:
BeforeInitialization : helloWorld Bean is going through init. AfterInitialization : helloWorld Your Message : Hello World! Bean will destroy now.
Spring — наследование определения бобов
Определение компонента может содержать много информации о конфигурации, включая аргументы конструктора, значения свойств и информацию, специфичную для контейнера, такую как метод инициализации, имя метода статической фабрики и т. Д.
Определение дочернего бина наследует данные конфигурации из родительского определения. Дочернее определение может переопределять некоторые значения или добавлять другие при необходимости.
Наследование определений Spring Bean не имеет ничего общего с наследованием классов Java, но концепция наследования такая же. Вы можете определить определение родительского компонента в качестве шаблона, а другие дочерние компоненты могут наследовать необходимую конфигурацию от родительского компонента.
Когда вы используете метаданные конфигурации на основе XML, вы указываете определение дочернего компонента с помощью атрибута parent , указывая родительский компонент в качестве значения этого атрибута.
пример
Давайте создадим рабочую среду Eclipse и предпримем следующие шаги для создания приложения Spring:
меры | Описание |
---|---|
1 | Создайте проект с именем SpringExample и создайте пакет com.tutorialspoint в папке src в созданном проекте. |
2 | Добавьте необходимые библиотеки Spring с помощью параметра « Добавить внешние JAR-файлы», как описано в главе « Пример Hello World» . |
3 | Создайте классы Java HelloWorld , HelloIndia и MainApp в пакете com.tutorialspoint . |
4 | Создайте файл конфигурации Beans Beans.xml в папке src . |
5 | Последний шаг — создать содержимое всех файлов Java и файла конфигурации Bean и запустить приложение, как описано ниже. |
Ниже приведен файл конфигурации Beans.xml, в котором мы определили bean-компонент helloWorld, который имеет два свойства message1 и message2 . Следующий bean-компонент «helloIndia» был определен как дочерний компонент «helloWorld» с использованием родительского атрибута. Дочерний компонент наследует свойство message2 как есть, переопределяет свойство message1 и вводит еще одно свойство message3 .
<?xml version = "1.0" encoding = "UTF-8"?> <beans xmlns = "http://www.springframework.org/schema/beans" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation = "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <bean id = "helloWorld" class = "com.tutorialspoint.HelloWorld"> <property name = "message1" value = "Hello World!"/> <property name = "message2" value = "Hello Second World!"/> </bean> <bean id ="helloIndia" class = "com.tutorialspoint.HelloIndia" parent = "helloWorld"> <property name = "message1" value = "Hello India!"/> <property name = "message3" value = "Namaste India!"/> </bean> </beans>
Вот содержимое файла HelloWorld.java —
package com.tutorialspoint; public class HelloWorld { private String message1; private String message2; public void setMessage1(String message){ this.message1 = message; } public void setMessage2(String message){ this.message2 = message; } public void getMessage1(){ System.out.println("World Message1 : " + message1); } public void getMessage2(){ System.out.println("World Message2 : " + message2); } }
Вот содержимое файла HelloIndia.java —
package com.tutorialspoint; public class HelloIndia { private String message1; private String message2; private String message3; public void setMessage1(String message){ this.message1 = message; } public void setMessage2(String message){ this.message2 = message; } public void setMessage3(String message){ this.message3 = message; } public void getMessage1(){ System.out.println("India Message1 : " + message1); } public void getMessage2(){ System.out.println("India Message2 : " + message2); } public void getMessage3(){ System.out.println("India Message3 : " + message3); } }
Ниже приводится содержание файла MainApp.java —
package com.tutorialspoint; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class MainApp { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml"); HelloWorld objA = (HelloWorld) context.getBean("helloWorld"); objA.getMessage1(); objA.getMessage2(); HelloIndia objB = (HelloIndia) context.getBean("helloIndia"); objB.getMessage1(); objB.getMessage2(); objB.getMessage3(); } }
Как только вы закончили создавать файлы конфигурации исходного кода и bean-компонента, давайте запустим приложение Если с вашим приложением все в порядке, оно напечатает следующее сообщение:
World Message1 : Hello World! World Message2 : Hello Second World! India Message1 : Hello India! India Message2 : Hello Second World! India Message3 : Namaste India!
Если вы заметили, что мы не передали message2 при создании bean-компонента helloIndia, но он был передан из-за наследования определения бина.
Шаблон определения бина
Вы можете создать шаблон определения компонента, который может использоваться другими определениями дочерних компонентов без особых усилий. При определении шаблона определения компонента не следует указывать атрибут класса, а также указывать абстрактный атрибут и указывать абстрактный атрибут со значением true, как показано в следующем фрагменте кода:
<?xml version = "1.0" encoding = "UTF-8"?> <beans xmlns = "http://www.springframework.org/schema/beans" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation = "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <bean id = "beanTeamplate" abstract = "true"> <property name = "message1" value = "Hello World!"/> <property name = "message2" value = "Hello Second World!"/> <property name = "message3" value = "Namaste India!"/> </bean> <bean id = "helloIndia" class = "com.tutorialspoint.HelloIndia" parent = "beanTeamplate"> <property name = "message1" value = "Hello India!"/> <property name = "message3" value = "Namaste India!"/> </bean> </beans>
Родительский бин не может быть создан самостоятельно, потому что он неполон, и он также явно помечен как абстрактный . Когда определение является абстрактным, как это, его можно использовать только как определение чистого шаблонного компонента, которое служит родительским определением для дочерних определений.
Весна — Внедрение Зависимости
Каждое Java-приложение имеет несколько объектов, которые работают вместе, чтобы представить то, что конечный пользователь видит в качестве рабочего приложения. При написании сложного Java-приложения классы приложения должны быть как можно более независимыми от других Java-классов, чтобы увеличить возможность повторного использования этих классов и тестировать их независимо от других классов во время модульного тестирования. Инъекция зависимостей (или иногда называемая проводкой) помогает склеивать эти классы и в то же время сохранять их независимость.
Предположим, у вас есть приложение, в котором есть компонент текстового редактора, и вы хотите обеспечить проверку орфографии. Ваш стандартный код будет выглядеть примерно так:
public class TextEditor { private SpellChecker spellChecker; public TextEditor() { spellChecker = new SpellChecker(); } }
Здесь мы создали зависимость между TextEditor и SpellChecker. В сценарии инверсии управления мы вместо этого сделали бы что-то вроде этого —
public class TextEditor { private SpellChecker spellChecker; public TextEditor(SpellChecker spellChecker) { this.spellChecker = spellChecker; } }
Здесь TextEditor не должен беспокоиться о реализации SpellChecker. SpellChecker будет реализован независимо и будет предоставлен TextEditor во время создания экземпляра TextEditor. Вся эта процедура контролируется Spring Framework.
Здесь мы удалили тотальный контроль из TextEditor и сохранили его где-то еще (например, файл конфигурации XML), а зависимость (т.е. класс SpellChecker) вводится в класс TextEditor через конструктор класса . Таким образом, поток управления был «инвертирован» с помощью Dependency Injection (DI), потому что вы фактически делегировали зависимости некоторой внешней системе.
Второй метод внедрения зависимости — через Setter Methods класса TextEditor, где мы создадим экземпляр SpellChecker. Этот экземпляр будет использоваться для вызова методов установки для инициализации свойств TextEditor.
Таким образом, DI существует в двух основных вариантах, и в следующих двух подразделах будут рассмотрены оба примера:
Sr.No. | Тип и описание внедрения зависимостей |
---|---|
1 | Внедрение зависимостей на основе конструктора
DI на основе конструктора выполняется, когда контейнер вызывает конструктор класса с несколькими аргументами, каждый из которых представляет зависимость от другого класса. |
2 | Внедрение зависимостей на основе установки
DI на основе установки выполняется контейнером, вызывающим методы setter для ваших bean-компонентов после вызова конструктора без аргументов или статического метода фабрики без аргументов для создания экземпляра вашего bean-компонента. |
DI на основе конструктора выполняется, когда контейнер вызывает конструктор класса с несколькими аргументами, каждый из которых представляет зависимость от другого класса.
DI на основе установки выполняется контейнером, вызывающим методы setter для ваших bean-компонентов после вызова конструктора без аргументов или статического метода фабрики без аргументов для создания экземпляра вашего bean-компонента.
Вы можете смешивать как DI на основе конструктора, так и на основе Setter, но рекомендуется использовать аргументы конструктора для обязательных зависимостей и setters для необязательных зависимостей.
Код чище с принципом DI, и разъединение более эффективно, когда объектам предоставлены их зависимости. Объект не просматривает свои зависимости и не знает местоположения или класса зависимостей, скорее всего Spring Framework позаботится обо всем.
Весна — впрыскивая внутреннюю фасоль
Как вы знаете, внутренние классы Java определены в области действия других классов, аналогично, внутренние компоненты — это компоненты, которые определены в области действия другого компонента. Таким образом, элемент <bean /> внутри элементов <property /> или <constructor-arg /> называется внутренним компонентом и показан ниже.
<?xml version = "1.0" encoding = "UTF-8"?> <beans xmlns = "http://www.springframework.org/schema/beans" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation = "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <bean id = "outerBean" class = "..."> <property name = "target"> <bean id = "innerBean" class = "..."/> </property> </bean> </beans>
пример
Давайте создадим рабочую среду Eclipse и выполните следующие шаги для создания приложения Spring:
меры | Описание |
---|---|
1 | Создайте проект с именем SpringExample и создайте пакет com.tutorialspoint в папке src в созданном проекте. |
2 | Добавьте необходимые библиотеки Spring с помощью параметра « Добавить внешние JAR-файлы», как описано в главе « Пример Hello World» . |
3 | Создайте классы Java TextEditor , SpellChecker и MainApp в пакете com.tutorialspoint . |
4 | Создайте файл конфигурации Beans Beans.xml в папке src . |
5 | Последний шаг — создать содержимое всех файлов Java и файла конфигурации Bean и запустить приложение, как описано ниже. |
Вот содержимое файла TextEditor.java —
package com.tutorialspoint; public class TextEditor { private SpellChecker spellChecker; // a setter method to inject the dependency. public void setSpellChecker(SpellChecker spellChecker) { System.out.println("Inside setSpellChecker." ); this.spellChecker = spellChecker; } // a getter method to return spellChecker public SpellChecker getSpellChecker() { return spellChecker; } public void spellCheck() { spellChecker.checkSpelling(); } }
Ниже приводится содержимое другого файла зависимого класса SpellChecker.java —
package com.tutorialspoint; public class SpellChecker { public SpellChecker(){ System.out.println("Inside SpellChecker constructor." ); } public void checkSpelling(){ System.out.println("Inside checkSpelling." ); } }
Ниже приводится содержание файла MainApp.java —
package com.tutorialspoint; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class MainApp { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml"); TextEditor te = (TextEditor) context.getBean("textEditor"); te.spellCheck(); } }
Ниже приведен файл конфигурации Beans.xml, в котором есть конфигурация для внедрения на основе метода установки, но с использованием внутренних компонентов.
<?xml version = "1.0" encoding = "UTF-8"?> <beans xmlns = "http://www.springframework.org/schema/beans" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation = "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <!-- Definition for textEditor bean using inner bean --> <bean id = "textEditor" class = "com.tutorialspoint.TextEditor"> <property name = "spellChecker"> <bean id = "spellChecker" class = "com.tutorialspoint.SpellChecker"/> </property> </bean> </beans>
Как только вы закончили создавать файлы конфигурации исходного кода и bean-компонента, давайте запустим приложение Если с вашим приложением все в порядке, оно напечатает следующее сообщение:
Inside SpellChecker constructor. Inside setSpellChecker. Inside checkSpelling.
Весна — инъекционная коллекция
Вы видели, как настроить примитивный тип данных, используя атрибуты значений и ссылки на объекты, используя атрибут ref тега <property> в вашем файле конфигурации Bean. Оба случая имеют дело с передачей единственного значения бобу.
Теперь, что если вы хотите передать множественные значения, такие как типы Java Collection, такие как List, Set, Map и Properties. Чтобы справиться с ситуацией, Spring предлагает четыре типа элементов конфигурации коллекции:
Sr.No | Элемент и описание |
---|---|
1 |
<список> Это помогает при подключении, т. Е. Вводит список значений, позволяя создавать дубликаты. |
2 |
<набор> Это помогает в связывании набора значений, но без дубликатов. |
3 |
<карта> Это может быть использовано для добавления коллекции пар имя-значение, где имя и значение могут быть любого типа. |
4 |
<подпорки> Это может быть использовано для добавления коллекции пар имя-значение, где имя и значение являются строками. |
<список>
Это помогает при подключении, т. Е. Вводит список значений, позволяя создавать дубликаты.
<набор>
Это помогает в связывании набора значений, но без дубликатов.
<карта>
Это может быть использовано для добавления коллекции пар имя-значение, где имя и значение могут быть любого типа.
<подпорки>
Это может быть использовано для добавления коллекции пар имя-значение, где имя и значение являются строками.
Вы можете использовать <list> или <set> для связи с любой реализацией java.util.Collection или массива .
Вы столкнетесь с двумя ситуациями: (а) передача прямых значений коллекции и (б) передача ссылки на компонент в качестве одного из элементов коллекции.
пример
Давайте создадим рабочую среду Eclipse и предпримем следующие шаги для создания приложения Spring:
меры | Описание |
---|---|
1 | Создайте проект с именем SpringExample и создайте пакет com.tutorialspoint в папке src в созданном проекте. |
2 | Добавьте необходимые библиотеки Spring с помощью параметра « Добавить внешние JAR-файлы», как описано в главе « Пример Hello World» . |
3 | Создайте классы Java JavaCollection и MainApp в пакете com.tutorialspoint . |
4 | Создайте файл конфигурации Beans Beans.xml в папке src . |
5 | Последний шаг — создать содержимое всех файлов Java и файла конфигурации Bean и запустить приложение, как описано ниже. |
Вот содержимое файла JavaCollection.java —
package com.tutorialspoint; import java.util.*; public class JavaCollection { List addressList; Set addressSet; Map addressMap; Properties addressProp; // a setter method to set List public void setAddressList(List addressList) { this.addressList = addressList; } // prints and returns all the elements of the list. public List getAddressList() { System.out.println("List Elements :" + addressList); return addressList; } // a setter method to set Set public void setAddressSet(Set addressSet) { this.addressSet = addressSet; } // prints and returns all the elements of the Set. public Set getAddressSet() { System.out.println("Set Elements :" + addressSet); return addressSet; } // a setter method to set Map public void setAddressMap(Map addressMap) { this.addressMap = addressMap; } // prints and returns all the elements of the Map. public Map getAddressMap() { System.out.println("Map Elements :" + addressMap); return addressMap; } // a setter method to set Property public void setAddressProp(Properties addressProp) { this.addressProp = addressProp; } // prints and returns all the elements of the Property. public Properties getAddressProp() { System.out.println("Property Elements :" + addressProp); return addressProp; } }
Ниже приводится содержание файла MainApp.java —
package com.tutorialspoint; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class MainApp { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml"); JavaCollection jc=(JavaCollection)context.getBean("javaCollection"); jc.getAddressList(); jc.getAddressSet(); jc.getAddressMap(); jc.getAddressProp(); } }
Ниже приведен файл конфигурации Beans.xml, в котором есть конфигурация для всех типов коллекций.
<?xml version = "1.0" encoding = "UTF-8"?> <beans xmlns = "http://www.springframework.org/schema/beans" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation = "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <!-- Definition for javaCollection --> <bean id = "javaCollection" class = "com.tutorialspoint.JavaCollection"> <!-- results in a setAddressList(java.util.List) call --> <property name = "addressList"> <list> <value>INDIA</value> <value>Pakistan</value> <value>USA</value> <value>USA</value> </list> </property> <!-- results in a setAddressSet(java.util.Set) call --> <property name = "addressSet"> <set> <value>INDIA</value> <value>Pakistan</value> <value>USA</value> <value>USA</value> </set> </property> <!-- results in a setAddressMap(java.util.Map) call --> <property name = "addressMap"> <map> <entry key = "1" value = "INDIA"/> <entry key = "2" value = "Pakistan"/> <entry key = "3" value = "USA"/> <entry key = "4" value = "USA"/> </map> </property> <!-- results in a setAddressProp(java.util.Properties) call --> <property name = "addressProp"> <props> <prop key = "one">INDIA</prop> <prop key = "one">INDIA</prop> <prop key = "two">Pakistan</prop> <prop key = "three">USA</prop> <prop key = "four">USA</prop> </props> </property> </bean> </beans>
Как только вы закончили создавать файлы конфигурации исходного кода и bean-компонента, давайте запустим приложение Если с вашим приложением все в порядке, оно напечатает следующее сообщение:
List Elements :[INDIA, Pakistan, USA, USA] Set Elements :[INDIA, Pakistan, USA] ap Elements :{1 = INDIA, 2 = Pakistan, 3 = USA, 4 = USA} Property Elements :{two = Pakistan, one = INDIA, three = USA, four = USA}
Внедрение ссылок на бин
Следующее определение Бина поможет вам понять, как внедрить ссылки на Бин как один из элементов коллекции. Даже вы можете смешивать ссылки и значения вместе, как показано в следующем фрагменте кода —
<?xml version = "1.0" encoding = "UTF-8"?> <beans xmlns = "http://www.springframework.org/schema/beans" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation = "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <!-- Bean Definition to handle references and values --> <bean id = "..." class = "..."> <!-- Passing bean reference for java.util.List --> <property name = "addressList"> <list> <ref bean = "address1"/> <ref bean = "address2"/> <value>Pakistan</value> </list> </property> <!-- Passing bean reference for java.util.Set --> <property name = "addressSet"> <set> <ref bean = "address1"/> <ref bean = "address2"/> <value>Pakistan</value> </set> </property> <!-- Passing bean reference for java.util.Map --> <property name = "addressMap"> <map> <entry key = "one" value = "INDIA"/> <entry key = "two" value-ref = "address1"/> <entry key = "three" value-ref = "address2"/> </map> </property> </bean> </beans>
Чтобы использовать приведенное выше определение bean-компонента, вам необходимо определить ваши методы установки так, чтобы они также могли обрабатывать ссылки.
Внедрение пустых и пустых строковых значений
Если вам нужно передать пустую строку в качестве значения, вы можете передать ее следующим образом:
<bean id = "..." class = "exampleBean"> <property name = "email" value = ""/> </bean>
Предыдущий пример эквивалентен коду Java: exampleBean.setEmail («»)
Если вам нужно передать значение NULL, вы можете передать его следующим образом:
<bean id = "..." class = "exampleBean"> <property name = "email"><null/></property> </bean>
Предыдущий пример эквивалентен коду Java: exampleBean.setEmail (null)
Весна — Бобы Авто-проводка
Вы узнали, как объявлять компоненты с помощью элемента <bean> и внедрять элементы <bean> с помощью элементов <constructor-arg> и <property> в файле конфигурации XML.
Контейнер Spring может автоматически связывать отношения между взаимодействующими компонентами без использования элементов <constructor-arg> и <property>, что помогает сократить объем XML-конфигурации, которую вы пишете для большого приложения на основе Spring.
Режимы автопроводки
Ниже приведены режимы автоматического подключения, которые можно использовать для указания контейнеру Spring использовать автоматическое подключение для внедрения зависимости. Вы используете атрибут autowire элемента <bean />, чтобы указать режим autowire для определения bean-компонента.
Sr.No | Режим и описание |
---|---|
1 | нет
Это настройка по умолчанию, которая означает отсутствие автоматического подключения, и вы должны использовать явную ссылку на компонент для подключения. Вам нечего делать специально для этой проводки. Это то, что вы уже видели в главе «Внедрение зависимостей». |
2 | по имени
Автопроводка по названию свойства. Контейнер Spring просматривает свойства bean-компонентов, для которых для атрибута autowire установлено значение byName в файле конфигурации XML. Затем он пытается сопоставить и связать свои свойства с bean-компонентами, определенными теми же именами в файле конфигурации. |
3 | ByType
Автопроводка по типу собственности. Контейнер Spring просматривает свойства bean-компонентов, для которых для атрибута autowire установлено значение byType в файле конфигурации XML. Затем он пытается сопоставить и связать свойство, если его тип соответствует точно одному из имен bean-компонентов в файле конфигурации. Если существует несколько таких бобов, возникает фатальное исключение. |
4 | конструктор
Аналогичен byType, но тип применяется к аргументам конструктора. Если в контейнере нет точно одного компонента с аргументом конструктора, возникает фатальная ошибка. |
5 | автоматическое распознавание
Spring сначала пытается подключиться с помощью autowire через конструктор , если он не работает, Spring пытается выполнить autowire by byType . |
Это настройка по умолчанию, которая означает отсутствие автоматического подключения, и вы должны использовать явную ссылку на компонент для подключения. Вам нечего делать специально для этой проводки. Это то, что вы уже видели в главе «Внедрение зависимостей».
Автопроводка по названию свойства. Контейнер Spring просматривает свойства bean-компонентов, для которых для атрибута autowire установлено значение byName в файле конфигурации XML. Затем он пытается сопоставить и связать свои свойства с bean-компонентами, определенными теми же именами в файле конфигурации.
Автопроводка по типу собственности. Контейнер Spring просматривает свойства bean-компонентов, для которых для атрибута autowire установлено значение byType в файле конфигурации XML. Затем он пытается сопоставить и связать свойство, если его тип соответствует точно одному из имен bean-компонентов в файле конфигурации. Если существует несколько таких бобов, возникает фатальное исключение.
Аналогичен byType, но тип применяется к аргументам конструктора. Если в контейнере нет точно одного компонента с аргументом конструктора, возникает фатальная ошибка.
Spring сначала пытается подключиться с помощью autowire через конструктор , если он не работает, Spring пытается выполнить autowire by byType .
Вы можете использовать ByType или режим автоматического подключения конструктора для подключения массивов и других типизированных коллекций.
Ограничения с автопроводкой
Автопроводка работает лучше всего, когда она используется последовательно в проекте. Если автопроводка не используется в целом, разработчикам может быть неудобно использовать ее для привязки только одного или двух определений компонента. Хотя автоматическая разводка может значительно снизить потребность в указании свойств или аргументов конструктора, но вы должны учитывать ограничения и недостатки автоподсоединения перед их использованием.
Sr.No. | Ограничения и описание |
---|---|
1 |
Превосходящая возможность Вы по-прежнему можете указывать зависимости, используя настройки <constructor-arg> и <property>, которые всегда переопределяют автопроводку. |
2 |
Примитивные типы данных Вы не можете автоматически связывать так называемые простые свойства, такие как примитивы, строки и классы. |
3 |
Запутанная природа Автопроводка менее точна, чем явная, поэтому, если возможно, предпочтительнее использовать явную проводку. |
Превосходящая возможность
Вы по-прежнему можете указывать зависимости, используя настройки <constructor-arg> и <property>, которые всегда переопределяют автопроводку.
Примитивные типы данных
Вы не можете автоматически связывать так называемые простые свойства, такие как примитивы, строки и классы.
Запутанная природа
Автопроводка менее точна, чем явная, поэтому, если возможно, предпочтительнее использовать явную проводку.
Spring — Конфигурация на основе аннотации
Начиная с Spring 2.5 стало возможным настраивать внедрение зависимостей с помощью аннотаций . Таким образом, вместо использования XML для описания связывания bean-компонентов, вы можете переместить конфигурацию bean-компонента в сам класс компонента, используя аннотации к соответствующему классу, методу или объявлению поля.
Добавление аннотации выполняется до внедрения XML. Таким образом, последняя конфигурация переопределяет первую для свойств, связанных через оба подхода.
По умолчанию проводка аннотации в контейнере Spring не включена. Поэтому, прежде чем мы сможем использовать проводку на основе аннотаций, нам нужно включить ее в нашем файле конфигурации Spring. Поэтому рассмотрите следующий файл конфигурации на случай, если вы хотите использовать какие-либо аннотации в приложении Spring.
<?xml version = "1.0" encoding = "UTF-8"?> <beans xmlns = "http://www.springframework.org/schema/beans" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xmlns:context = "http://www.springframework.org/schema/context" xsi:schemaLocation = "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <context:annotation-config/> <!-- bean definitions go here --> </beans>
Как только <context: annotation-config /> настроен, вы можете начать комментировать свой код, чтобы указать, что Spring должен автоматически связывать значения в свойствах, методах и конструкторах. Давайте посмотрим на несколько важных аннотаций, чтобы понять, как они работают —
Sr.No. | Аннотация и описание |
---|---|
1 | @Необходимые
Аннотация @Required применяется к методам установки свойств бина. |
2 | @Autowired
Аннотация @Autowired может применяться к методам установки свойств бина, методам без установки, конструктору и свойствам. |
3 | @Qualifier
Аннотацию @Qualifier вместе с @Autowired можно использовать для устранения путаницы, указав, какой именно компонент будет подключен. |
4 | JSR-250 Аннотации
Spring поддерживает аннотации на основе JSR-250, которые включают аннотации @Resource, @PostConstruct и @PreDestroy. |
Аннотация @Required применяется к методам установки свойств бина.
Аннотация @Autowired может применяться к методам установки свойств бина, методам без установки, конструктору и свойствам.
Аннотацию @Qualifier вместе с @Autowired можно использовать для устранения путаницы, указав, какой именно компонент будет подключен.
Spring поддерживает аннотации на основе JSR-250, которые включают аннотации @Resource, @PostConstruct и @PreDestroy.
Spring — конфигурация на основе Java
До сих пор вы видели, как мы конфигурируем компоненты Spring с помощью файла конфигурации XML. Если вы знакомы с конфигурацией XML, то на самом деле нет необходимости изучать, как приступить к настройке на основе Java, поскольку вы собираетесь достичь того же результата, используя любую из доступных конфигураций.
Опция конфигурации на основе Java позволяет вам писать большую часть конфигурации Spring без XML, но с помощью нескольких аннотаций на основе Java, описанных в этой главе.
@ Конфигурация и аннотации @Bean
Аннотирование класса с помощью @Configuration указывает, что класс может использоваться контейнером IoC Spring в качестве источника определений бина. Аннотация @Bean сообщает Spring, что метод, аннотированный @Bean, вернет объект, который должен быть зарегистрирован как компонент в контексте приложения Spring. Простейший класс @Configuration был бы следующим:
package com.tutorialspoint; import org.springframework.context.annotation.*; @Configuration public class HelloWorldConfig { @Bean public HelloWorld helloWorld(){ return new HelloWorld(); } }
Приведенный выше код будет эквивалентен следующей конфигурации XML —
<beans> <bean id = "helloWorld" class = "com.tutorialspoint.HelloWorld" /> </beans>
Здесь имя метода с комментариями @Bean работает как идентификатор компонента, и оно создает и возвращает фактический компонент. Ваш класс конфигурации может иметь объявление для нескольких @Bean. После того, как ваши классы конфигурации определены, вы можете загрузить и предоставить их контейнеру Spring с помощью AnnotationConfigApplicationContext следующим образом:
public static void main(String[] args) { ApplicationContext ctx = new AnnotationConfigApplicationContext(HelloWorldConfig.class); HelloWorld helloWorld = ctx.getBean(HelloWorld.class); helloWorld.setMessage("Hello World!"); helloWorld.getMessage(); }
Вы можете загрузить различные классы конфигурации следующим образом:
public static void main(String[] args) { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); ctx.register(AppConfig.class, OtherConfig.class); ctx.register(AdditionalConfig.class); ctx.refresh(); MyService myService = ctx.getBean(MyService.class); myService.doStuff(); }
пример
Давайте создадим рабочую среду Eclipse и предпримем следующие шаги для создания приложения Spring:
меры | Описание |
---|---|
1 | Создайте проект с именем SpringExample и создайте пакет com.tutorialspoint в папке src в созданном проекте. |
2 | Добавьте необходимые библиотеки Spring с помощью параметра « Добавить внешние JAR-файлы», как описано в главе « Пример Hello World» . |
3 | Поскольку вы используете аннотации на основе Java, вам также необходимо добавить CGLIB.jar из установочного каталога Java и библиотеку ASM.jar, которую можно загрузить с asm.ow2.org . |
4 | Создайте классы Java HelloWorldConfig , HelloWorld и MainApp в пакете com.tutorialspoint . |
5 | Последний шаг — создать содержимое всех файлов Java и файла конфигурации Bean и запустить приложение, как описано ниже. |
Вот содержимое файла HelloWorldConfig.java
package com.tutorialspoint; import org.springframework.context.annotation.*; @Configuration public class HelloWorldConfig { @Bean public HelloWorld helloWorld(){ return new HelloWorld(); } }
Вот содержимое файла HelloWorld.java
package com.tutorialspoint; public class HelloWorld { private String message; public void setMessage(String message){ this.message = message; } public void getMessage(){ System.out.println("Your Message : " + message); } }
Ниже приводится содержание файла MainApp.java
package com.tutorialspoint; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.*; public class MainApp { public static void main(String[] args) { ApplicationContext ctx = new AnnotationConfigApplicationContext(HelloWorldConfig.class); HelloWorld helloWorld = ctx.getBean(HelloWorld.class); helloWorld.setMessage("Hello World!"); helloWorld.getMessage(); } }
Как только вы закончите создание всех исходных файлов и добавление необходимых дополнительных библиотек, давайте запустим приложение. Обратите внимание, что файл конфигурации не требуется. Если с вашим приложением все в порядке, оно напечатает следующее сообщение:
Your Message : Hello World!
Внедрение бобовых зависимостей
Когда @Beans имеют зависимости друг от друга, это означает, что зависимость так же проста, как один метод bean, вызывающий другой, следующим образом:
package com.tutorialspoint; import org.springframework.context.annotation.*; @Configuration public class AppConfig { @Bean public Foo foo() { return new Foo(bar()); } @Bean public Bar bar() { return new Bar(); } }
Здесь бин foo получает ссылку на bar посредством инжектора конструктора. Теперь давайте посмотрим на другой рабочий пример.
пример
Давайте создадим рабочую среду Eclipse и предпримем следующие шаги для создания приложения Spring:
меры | Описание |
---|---|
1 | Создайте проект с именем SpringExample и создайте пакет com.tutorialspoint в папке src в созданном проекте. |
2 | Добавьте необходимые библиотеки Spring с помощью параметра « Добавить внешние JAR-файлы», как описано в главе « Пример Hello World» . |
3 | Поскольку вы используете аннотации на основе Java, вам также необходимо добавить CGLIB.jar из установочного каталога Java и библиотеку ASM.jar, которую можно загрузить с asm.ow2.org . |
4 | Создайте классы Java TextEditorConfig , TextEditor , SpellChecker и MainApp в пакете com.tutorialspoint . |
5 | Последний шаг — создать содержимое всех файлов Java и файла конфигурации Bean и запустить приложение, как описано ниже. |
Вот содержимое файла TextEditorConfig.java
package com.tutorialspoint; import org.springframework.context.annotation.*; @Configuration public class TextEditorConfig { @Bean public TextEditor textEditor(){ return new TextEditor( spellChecker() ); } @Bean public SpellChecker spellChecker(){ return new SpellChecker( ); } }
Вот содержимое файла TextEditor.java
package com.tutorialspoint; public class TextEditor { private SpellChecker spellChecker; public TextEditor(SpellChecker spellChecker){ System.out.println("Inside TextEditor constructor." ); this.spellChecker = spellChecker; } public void spellCheck(){ spellChecker.checkSpelling(); } }
Ниже приводится содержимое другого файла зависимого класса SpellChecker.java
package com.tutorialspoint; public class SpellChecker { public SpellChecker(){ System.out.println("Inside SpellChecker constructor." ); } public void checkSpelling(){ System.out.println("Inside checkSpelling." ); } }
Ниже приводится содержание файла MainApp.java
package com.tutorialspoint; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.*; public class MainApp { public static void main(String[] args) { ApplicationContext ctx = new AnnotationConfigApplicationContext(TextEditorConfig.class); TextEditor te = ctx.getBean(TextEditor.class); te.spellCheck(); } }
Как только вы закончите создание всех исходных файлов и добавление необходимых дополнительных библиотек, давайте запустим приложение. Обратите внимание, что файл конфигурации не требуется. Если с вашим приложением все в порядке, оно напечатает следующее сообщение:
Inside SpellChecker constructor. Inside TextEditor constructor. Inside checkSpelling.
@Import Аннотация
Аннотация @Import позволяет загружать определения @Bean из другого класса конфигурации. Рассмотрим класс ConfigA следующим образом:
@Configuration public class ConfigA { @Bean public A a() { return new A(); } }
Вы можете импортировать вышеуказанную декларацию Bean в другую декларацию Bean следующим образом:
@Configuration @Import(ConfigA.class) public class ConfigB { @Bean public B b() { return new B(); } }
Теперь вместо того, чтобы указывать ConfigA.class и ConfigB.class при создании экземпляра контекста, необходимо указать только ConfigB следующим образом:
public static void main(String[] args) { ApplicationContext ctx = new AnnotationConfigApplicationContext(ConfigB.class); // now both beans A and B will be available... A a = ctx.getBean(A.class); B b = ctx.getBean(B.class); }
Обратные вызовы жизненного цикла
Аннотация @Bean поддерживает указание произвольных методов обратного вызова инициализации и уничтожения, во многом как атрибуты init-method и destroy-метода Spring XML для элемента bean —
public class Foo { public void init() { // initialization logic } public void cleanup() { // destruction logic } } @Configuration public class AppConfig { @Bean(initMethod = "init", destroyMethod = "cleanup" ) public Foo foo() { return new Foo(); } }
Указание объема бобов
Область по умолчанию — singleton, но вы можете переопределить это с помощью аннотации @Scope следующим образом:
@Configuration public class AppConfig { @Bean @Scope("prototype") public Foo foo() { return new Foo(); } }
Обработка событий весной
Во всех главах вы видели, что ядром Spring является ApplicationContext , который управляет полным жизненным циклом bean-компонентов. ApplicationContext публикует определенные типы событий при загрузке бинов. Например, ContextStartedEvent публикуется при запуске контекста, а ContextStoppedEvent публикуется при остановке контекста.
Обработка событий в ApplicationContext обеспечивается через класс ApplicationEvent и интерфейс ApplicationListener . Следовательно, если компонент реализует ApplicationListener , то каждый раз, когда ApplicationEvent публикуется в ApplicationContext, этот компонент уведомляется.
Spring предоставляет следующие стандартные события —
Sr.No. | Весенние встроенные события и описание |
---|---|
1 |
ContextRefreshedEvent Это событие публикуется, когда ApplicationContext инициализируется или обновляется. Это также можно поднять с помощью метода refresh () в интерфейсе ConfigurableApplicationContext . |
2 |
ContextStartedEvent Это событие публикуется, когда ApplicationContext запускается с помощью метода start () в интерфейсе ConfigurableApplicationContext . Вы можете опросить свою базу данных или перезапустить любое остановленное приложение после получения этого события. |
3 |
ContextStoppedEvent Это событие публикуется, когда ApplicationContext останавливается с помощью метода stop () в интерфейсе ConfigurableApplicationContext . Вы можете выполнять необходимую работу по дому после получения этого события. |
4 |
ContextClosedEvent Это событие публикуется, когда ApplicationContext закрывается с помощью метода close () в интерфейсе ConfigurableApplicationContext . Закрытый контекст достигает конца жизни; это не может быть обновлено или перезапущено. |
5 |
RequestHandledEvent Это веб-событие, сообщающее всем компонентам, что HTTP-запрос был обслужен. |
ContextRefreshedEvent
Это событие публикуется, когда ApplicationContext инициализируется или обновляется. Это также можно поднять с помощью метода refresh () в интерфейсе ConfigurableApplicationContext .
ContextStartedEvent
Это событие публикуется, когда ApplicationContext запускается с помощью метода start () в интерфейсе ConfigurableApplicationContext . Вы можете опросить свою базу данных или перезапустить любое остановленное приложение после получения этого события.
ContextStoppedEvent
Это событие публикуется, когда ApplicationContext останавливается с помощью метода stop () в интерфейсе ConfigurableApplicationContext . Вы можете выполнять необходимую работу по дому после получения этого события.
ContextClosedEvent
Это событие публикуется, когда ApplicationContext закрывается с помощью метода close () в интерфейсе ConfigurableApplicationContext . Закрытый контекст достигает конца жизни; это не может быть обновлено или перезапущено.
RequestHandledEvent
Это веб-событие, сообщающее всем компонентам, что HTTP-запрос был обслужен.
Обработка событий Spring является однопоточной, поэтому, если событие опубликовано, до тех пор, пока все получатели не получат сообщение, процессы будут заблокированы, и поток не будет продолжен. Следовательно, следует проявлять осторожность при разработке приложения, если будет использоваться обработка событий.
Прослушивание контекстных событий
Чтобы прослушивать контекстное событие, компонент должен реализовывать интерфейс ApplicationListener, который имеет только один метод onApplicationEvent () . Итак, давайте напишем пример, чтобы увидеть, как события распространяются и как вы можете использовать свой код для выполнения требуемой задачи на основе определенных событий.
Давайте создадим рабочую среду Eclipse и предпримем следующие шаги для создания приложения Spring:
шаг | Описание |
---|---|
1 | Создайте проект с именем SpringExample и создайте пакет com.tutorialspoint в папке src в созданном проекте. |
2 | Добавьте необходимые библиотеки Spring с помощью параметра « Добавить внешние JAR-файлы», как описано в главе « Пример Hello World» . |
3 | Создайте классы Java HelloWorld , CStartEventHandler , CStopEventHandler и MainApp в пакете com.tutorialspoint . |
4 | Создайте файл конфигурации Beans Beans.xml в папке src . |
5 | Последний шаг — создать содержимое всех файлов Java и файла конфигурации Bean и запустить приложение, как описано ниже. |
Вот содержимое файла HelloWorld.java
package com.tutorialspoint; public class HelloWorld { private String message; public void setMessage(String message){ this.message = message; } public void getMessage(){ System.out.println("Your Message : " + message); } }
Ниже приводится содержание файла CStartEventHandler.java
package com.tutorialspoint; import org.springframework.context.ApplicationListener; import org.springframework.context.event.ContextStartedEvent; public class CStartEventHandler implements ApplicationListener<ContextStartedEvent>{ public void onApplicationEvent(ContextStartedEvent event) { System.out.println("ContextStartedEvent Received"); } }
Ниже приводится содержимое файла CStopEventHandler.java.
package com.tutorialspoint; import org.springframework.context.ApplicationListener; import org.springframework.context.event.ContextStoppedEvent; public class CStopEventHandler implements ApplicationListener<ContextStoppedEvent>{ public void onApplicationEvent(ContextStoppedEvent event) { System.out.println("ContextStoppedEvent Received"); } }
Ниже приводится содержание файла MainApp.java
package com.tutorialspoint; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class MainApp { public static void main(String[] args) { ConfigurableApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml"); // Let us raise a start event. context.start(); HelloWorld obj = (HelloWorld) context.getBean("helloWorld"); obj.getMessage(); // Let us raise a stop event. context.stop(); } }
Ниже приведен файл конфигурации Beans.xml
<?xml version = "1.0" encoding = "UTF-8"?> <beans xmlns = "http://www.springframework.org/schema/beans" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation = "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <bean id = "helloWorld" class = "com.tutorialspoint.HelloWorld"> <property name = "message" value = "Hello World!"/> </bean> <bean id = "cStartEventHandler" class = "com.tutorialspoint.CStartEventHandler"/> <bean id = "cStopEventHandler" class = "com.tutorialspoint.CStopEventHandler"/> </beans>
Как только вы закончили создавать файлы конфигурации исходного кода и bean-компонента, давайте запустим приложение Если с вашим приложением все в порядке, оно напечатает следующее сообщение:
ContextStartedEvent Received Your Message : Hello World! ContextStoppedEvent Received
При желании вы можете опубликовать свои собственные пользовательские события, а затем вы можете захватить их, чтобы предпринять какие-либо действия против этих пользовательских событий. Если вы заинтересованы в написании собственных пользовательских событий, вы можете проверить пользовательские события весной.
Пользовательские события весной
Существует ряд шагов, которые необходимо предпринять, чтобы написать и опубликовать свои собственные события. Следуйте инструкциям, приведенным в этой главе, для написания, публикации и обработки пользовательских событий Spring.
меры | Описание |
---|---|
1 | Создайте проект с именем SpringExample и создайте пакет com.tutorialspoint в папке src в созданном проекте. Все классы будут созданы в рамках этого пакета. |
2 | Добавьте необходимые библиотеки Spring с помощью параметра « Добавить внешние JAR-файлы», как описано в главе « Пример Hello World» . |
3 | Создайте класс события CustomEvent , расширив ApplicationEvent . Этот класс должен определять конструктор по умолчанию, который должен наследовать конструктор от класса ApplicationEvent. |
4 | Как только ваш класс событий определен, вы можете опубликовать его из любого класса, скажем, EventClassPublisher, который реализует ApplicationEventPublisherAware . Вам также необходимо объявить этот класс в файле конфигурации XML как компонент, чтобы контейнер мог идентифицировать компонент как издатель событий, поскольку он реализует интерфейс ApplicationEventPublisherAware. |
5 | Опубликованное событие может быть обработано в классе, скажем, EventClassHandler, который реализует интерфейс ApplicationListener и реализует метод onApplicationEvent для пользовательского события. |
6 | Создайте файл конфигурации beans.xml в папке src и класс MainApp, который будет работать как приложение Spring. |
7 | Последний шаг — создать содержимое всех файлов Java и файла конфигурации Bean и запустить приложение, как описано ниже. |
Вот содержимое файла CustomEvent.java
package com.tutorialspoint; import org.springframework.context.ApplicationEvent; public class CustomEvent extends ApplicationEvent{ public CustomEvent(Object source) { super(source); } public String toString(){ return "My Custom Event"; } }
Ниже приводится содержимое файла CustomEventPublisher.java.
package com.tutorialspoint; import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.ApplicationEventPublisherAware; public class CustomEventPublisher implements ApplicationEventPublisherAware { private ApplicationEventPublisher publisher; public void setApplicationEventPublisher (ApplicationEventPublisher publisher) { this.publisher = publisher; } public void publish() { CustomEvent ce = new CustomEvent(this); publisher.publishEvent(ce); } }
Ниже приводится содержимое файла CustomEventHandler.java.
package com.tutorialspoint; import org.springframework.context.ApplicationListener; public class CustomEventHandler implements ApplicationListener<CustomEvent> { public void onApplicationEvent(CustomEvent event) { System.out.println(event.toString()); } }
Ниже приводится содержание файла MainApp.java
package com.tutorialspoint; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class MainApp { public static void main(String[] args) { ConfigurableApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml"); CustomEventPublisher cvp = (CustomEventPublisher) context.getBean("customEventPublisher"); cvp.publish(); cvp.publish(); } }
Ниже приведен файл конфигурации Beans.xml
<?xml version = "1.0" encoding = "UTF-8"?> <beans xmlns = "http://www.springframework.org/schema/beans" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation = "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <bean id = "customEventHandler" class = "com.tutorialspoint.CustomEventHandler"/> <bean id = "customEventPublisher" class = "com.tutorialspoint.CustomEventPublisher"/> </beans>
Как только вы закончили создавать файлы конфигурации исходного кода и bean-компонента, давайте запустим приложение Если с вашим приложением все в порядке, оно напечатает следующее сообщение:
y Custom Event y Custom Event
АОП с Spring Framework
Одним из ключевых компонентов Spring Framework является структура Аспектно-ориентированного программирования (AOP) . Аспектно-ориентированное программирование влечет за собой разделение логики программы на отдельные части, называемые так называемыми проблемами. Функции, охватывающие несколько точек приложения, называются сквозными задачами, и эти сквозные задачи концептуально отделены от бизнес-логики приложения. Существуют различные общие хорошие примеры таких аспектов, как ведение журнала, аудит, декларативные транзакции, безопасность, кэширование и т. Д.
Ключевой единицей модульности в ООП является класс, тогда как в АОП единицей модульности является аспект. Внедрение зависимостей помогает отделить объекты приложения друг от друга, а AOP помогает отделить сквозные задачи от объектов, на которые они влияют. AOP подобен триггерам в таких языках программирования, как Perl, .NET, Java и других.
Модуль Spring AOP предоставляет перехватчики для перехвата приложения. Например, когда метод выполняется, вы можете добавить дополнительные функции до или после выполнения метода.
АОП Терминологии
Прежде чем мы начнем работать с AOP, давайте ознакомимся с концепциями и терминологией AOP. Эти термины не являются специфическими для Spring, скорее они связаны с AOP.
Sr.No | Условия и описание |
---|---|
1 |
аспект Это модуль, который имеет набор API, обеспечивающих сквозные требования. Например, модуль регистрации будет называться аспектом AOP для регистрации. Приложение может иметь любое количество аспектов в зависимости от требования. |
2 |
Точка соединения Это представляет собой точку в вашем приложении, где вы можете подключить аспект AOP. Вы также можете сказать, что это фактическое место в приложении, где будет выполняться действие с использованием среды Spring AOP. |
3 |
Совет Это фактическое действие, которое должно быть выполнено либо до, либо после выполнения метода. Это фактический фрагмент кода, который вызывается во время выполнения программы средой Spring AOP. |
4 |
Pointcut Это набор из одной или нескольких точек соединения, в которых должен выполняться совет. Вы можете указать pointcut, используя выражения или шаблоны, как мы увидим в наших примерах AOP. |
5 |
Вступление Введение позволяет добавлять новые методы или атрибуты к существующим классам. |
6 |
Целевой объект Объект рекомендуется одним или несколькими аспектами. Этот объект всегда будет прокси-объектом, также называемым рекомендованным объектом. |
7 |
ткачество Плетение — это процесс связывания аспектов с другими типами приложений или объектами для создания рекомендованного объекта. Это может быть сделано во время компиляции, загрузки или во время выполнения. |
аспект
Это модуль, который имеет набор API, обеспечивающих сквозные требования. Например, модуль регистрации будет называться аспектом AOP для регистрации. Приложение может иметь любое количество аспектов в зависимости от требования.
Точка соединения
Это представляет собой точку в вашем приложении, где вы можете подключить аспект AOP. Вы также можете сказать, что это фактическое место в приложении, где будет выполняться действие с использованием среды Spring AOP.
Совет
Это фактическое действие, которое должно быть выполнено либо до, либо после выполнения метода. Это фактический фрагмент кода, который вызывается во время выполнения программы средой Spring AOP.
Pointcut
Это набор из одной или нескольких точек соединения, в которых должен выполняться совет. Вы можете указать pointcut, используя выражения или шаблоны, как мы увидим в наших примерах AOP.
Вступление
Введение позволяет добавлять новые методы или атрибуты к существующим классам.
Целевой объект
Объект рекомендуется одним или несколькими аспектами. Этот объект всегда будет прокси-объектом, также называемым рекомендованным объектом.
ткачество
Плетение — это процесс связывания аспектов с другими типами приложений или объектами для создания рекомендованного объекта. Это может быть сделано во время компиляции, загрузки или во время выполнения.
Типы Советов
Аспекты Spring могут работать с пятью советами, упомянутыми ниже:
Sr.No | Советы и описание |
---|---|
1 |
до Запустите совет перед выполнением метода. |
2 |
после Запускайте совет после выполнения метода, независимо от его результата. |
3 |
после возвращения Запускайте рекомендацию после выполнения метода, только если метод завершается успешно. |
4 |
после того, как бросание Запускайте рекомендацию после выполнения метода, только если метод завершается с помощью исключения. |
5 |
вокруг Выполните совет до и после вызова рекомендованного метода. |
до
Запустите совет перед выполнением метода.
после
Запускайте совет после выполнения метода, независимо от его результата.
после возвращения
Запускайте рекомендацию после выполнения метода, только если метод завершается успешно.
после того, как бросание
Запускайте рекомендацию после выполнения метода, только если метод завершается с помощью исключения.
вокруг
Выполните совет до и после вызова рекомендованного метода.
Реализация пользовательских аспектов
Spring поддерживает подход стиля аннотации @AspectJ и подход на основе схемы для реализации пользовательских аспектов. Эти два подхода были подробно объяснены в следующих разделах.
Sr.No | Подход и описание |
---|---|
1 | На основе схемы XML
Аспекты реализуются с использованием обычных классов наряду с конфигурацией на основе XML. |
2 | На основе @AspectJ
@AspectJ относится к стилю объявления аспектов как обычных классов Java, аннотированных аннотациями Java 5. |
Аспекты реализуются с использованием обычных классов наряду с конфигурацией на основе XML.
@AspectJ относится к стилю объявления аспектов как обычных классов Java, аннотированных аннотациями Java 5.
Spring — Обзор JDBC Framework
При работе с базой данных, использующей старый старый JDBC, становится неудобно писать ненужный код для обработки исключений, открывать и закрывать соединения с базой данных и т. Д. Однако Spring JDBC Framework заботится обо всех низкоуровневых деталях, начиная с открытия соединения, подготавливая выполнить оператор SQL, обработать исключения, обработать транзакции и, наконец, закрыть соединение.
Итак, вам нужно просто определить параметры соединения и указать оператор SQL, который будет выполняться, и выполнять необходимую работу для каждой итерации при извлечении данных из базы данных.
Spring JDBC предоставляет несколько подходов и соответственно разные классы для взаимодействия с базой данных. Я собираюсь взять классический и самый популярный подход, который использует класс JdbcTemplate платформы. Это центральный базовый класс, который управляет всеми коммуникациями базы данных и обработкой исключений.
JdbcTemplate Class
Класс JDBC Template выполняет SQL-запросы, обновляет операторы, сохраняет вызовы процедур, выполняет итерацию по ResultSets и извлекает возвращенные значения параметров. Он также перехватывает исключения JDBC и переводит их в общую, более информативную иерархию исключений, определенную в пакете org.springframework.dao.
Экземпляры класса JdbcTemplate являются поточно-ориентированными после настройки. Таким образом, вы можете настроить один экземпляр JdbcTemplate, а затем безопасно внедрить эту общую ссылку в несколько DAO.
Обычной практикой при использовании класса Template JDBC является конфигурирование DataSource в вашем файле конфигурации Spring, а затем добавление зависимостей в этот общий компонент DataSource в ваши классы DAO, и в установщике для DataSource создается JdbcTemplate.
Настройка источника данных
Давайте создадим таблицу базы данных Student в нашей базе данных TEST . Мы предполагаем, что вы работаете с базой данных MySQL, если вы работаете с любой другой базой данных, вы можете соответствующим образом изменить ваши запросы DDL и SQL.
CREATE TABLE Student( ID INT NOT NULL AUTO_INCREMENT, NAME VARCHAR(20) NOT NULL, AGE INT NOT NULL, PRIMARY KEY (ID) );
Теперь нам нужно предоставить источник данных для шаблона JDBC, чтобы он мог сам настраиваться для получения доступа к базе данных. Вы можете настроить источник данных в XML-файле с помощью фрагмента кода, как показано в следующем фрагменте кода:
<bean id = "dataSource" class = "org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name = "driverClassName" value = "com.mysql.jdbc.Driver"/> <property name = "url" value = "jdbc:mysql://localhost:3306/TEST"/> <property name = "username" value = "root"/> <property name = "password" value = "password"/> </bean>
Объект доступа к данным (DAO)
DAO обозначает объект доступа к данным, который обычно используется для взаимодействия с базой данных. DAO существуют для предоставления средств для чтения и записи данных в базу данных, и они должны предоставлять эту функциональность через интерфейс, через который остальные приложения будут получать к ним доступ.
Поддержка DAO в Spring упрощает совместную работу с такими технологиями доступа к данным, как JDBC, Hibernate, JPA или JDO.
Выполнение операторов SQL
Давайте посмотрим, как мы можем выполнить операцию CRUD (создание, чтение, обновление и удаление) для таблиц базы данных, используя объект шаблона SQL и JDBC.
Запрос целого числа
String SQL = "select count(*) from Student"; int rowCount = jdbcTemplateObject.queryForInt( SQL );
Запрашивать долго
String SQL = "select count(*) from Student"; long rowCount = jdbcTemplateObject.queryForLong( SQL );
Простой запрос с использованием переменной связывания
String SQL = "select age from Student where id = ?"; int age = jdbcTemplateObject.queryForInt(SQL, new Object[]{10});
Запрашивая строку
String SQL = "select name from Student where id = ?"; String name = jdbcTemplateObject.queryForObject(SQL, new Object[]{10}, String.class);
Запрос и возврат объекта
String SQL = "select * from Student where id = ?"; Student student = jdbcTemplateObject.queryForObject( SQL, new Object[]{10}, new StudentMapper()); public class StudentMapper implements RowMapper<Student> { public Student mapRow(ResultSet rs, int rowNum) throws SQLException { Student student = new Student(); student.setID(rs.getInt("id")); student.setName(rs.getString("name")); student.setAge(rs.getInt("age")); return student; } }
Запрос и возврат нескольких объектов
String SQL = "select * from Student"; List<Student> students = jdbcTemplateObject.query( SQL, new StudentMapper()); public class StudentMapper implements RowMapper<Student> { public Student mapRow(ResultSet rs, int rowNum) throws SQLException { Student student = new Student(); student.setID(rs.getInt("id")); student.setName(rs.getString("name")); student.setAge(rs.getInt("age")); return student; } }
Вставка строки в таблицу
String SQL = "insert into Student (name, age) values (?, ?)"; jdbcTemplateObject.update( SQL, new Object[]{"Zara", 11} );
Обновление строки в таблице
String SQL = "update Student set name = ? where id = ?"; jdbcTemplateObject.update( SQL, new Object[]{"Zara", 10} );
Удаление строки из таблицы
String SQL = "delete Student where id = ?"; jdbcTemplateObject.update( SQL, new Object[]{20} );
Выполнение заявлений DDL
Вы можете использовать метод execute (..) из jdbcTemplate для выполнения любых операторов SQL или операторов DDL. Ниже приведен пример использования оператора CREATE для создания таблицы:
String SQL = "CREATE TABLE Student( " + "ID INT NOT NULL AUTO_INCREMENT, " + "NAME VARCHAR(20) NOT NULL, " + "AGE INT NOT NULL, " + "PRIMARY KEY (ID));" jdbcTemplateObject.execute( SQL );
Spring JDBC Framework Примеры
Основываясь на вышеизложенных концепциях, давайте проверим несколько важных примеров, которые помогут вам понять использование инфраструктуры JDBC в Spring —
Sr.No. | Пример и описание |
---|---|
1 | Spring JDBC Пример
В этом примере объясняется, как написать простое приложение Spring на основе JDBC. |
2 | Хранимая процедура SQL в Spring
Узнайте, как вызвать хранимую процедуру SQL при использовании JDBC в Spring. |
В этом примере объясняется, как написать простое приложение Spring на основе JDBC.
Узнайте, как вызвать хранимую процедуру SQL при использовании JDBC в Spring.
Весна — Управление транзакциями
Транзакция базы данных — это последовательность действий, которые рассматриваются как единая единица работы. Эти действия должны либо полностью завершиться, либо вообще не иметь никакого эффекта. Управление транзакциями является важной частью корпоративного приложения, ориентированного на СУБД, для обеспечения целостности и согласованности данных. Концепция транзакций может быть описана следующими четырьмя ключевыми свойствами, описанными как ACID —
-
Атомарность . Транзакция должна рассматриваться как единая операция, что означает, что вся последовательность операций является успешной или неудачной.
-
Согласованность — представляет согласованность ссылочной целостности базы данных, уникальных первичных ключей в таблицах и т. Д.
-
Изоляция — может быть много обработок транзакций с одним и тем же набором данных одновременно. Каждая транзакция должна быть изолирована от других, чтобы предотвратить повреждение данных.
-
Долговечность — после завершения транзакции ее результаты должны быть постоянными и не могут быть удалены из базы данных из-за сбоя системы.
Атомарность . Транзакция должна рассматриваться как единая операция, что означает, что вся последовательность операций является успешной или неудачной.
Согласованность — представляет согласованность ссылочной целостности базы данных, уникальных первичных ключей в таблицах и т. Д.
Изоляция — может быть много обработок транзакций с одним и тем же набором данных одновременно. Каждая транзакция должна быть изолирована от других, чтобы предотвратить повреждение данных.
Долговечность — после завершения транзакции ее результаты должны быть постоянными и не могут быть удалены из базы данных из-за сбоя системы.
Реальная система баз данных СУБД будет гарантировать все четыре свойства для каждой транзакции. Упрощенный вид транзакции, выданной в базу данных с использованием SQL, выглядит следующим образом:
-
Начните транзакцию, используя команду начала транзакции .
-
Выполните различные операции удаления, обновления или вставки с использованием запросов SQL.
-
Если все операции выполнены успешно, выполните коммит, иначе откатите все операции.
Начните транзакцию, используя команду начала транзакции .
Выполните различные операции удаления, обновления или вставки с использованием запросов SQL.
Если все операции выполнены успешно, выполните коммит, иначе откатите все операции.
Spring Framework предоставляет абстрактный слой поверх различных базовых API-интерфейсов управления транзакциями. Поддержка транзакций Spring направлена на предоставление альтернативы транзакциям EJB путем добавления возможностей транзакций в POJO. Spring поддерживает как программное, так и декларативное управление транзакциями. Для EJB требуется сервер приложений, но управление транзакциями Spring может быть реализовано без сервера приложений.
Местные и глобальные транзакции
Локальные транзакции относятся к одному транзакционному ресурсу, такому как соединение JDBC, тогда как глобальные транзакции могут охватывать несколько транзакционных ресурсов, например транзакции в распределенной системе.
Локальное управление транзакциями может быть полезным в централизованной вычислительной среде, где компоненты и ресурсы приложения расположены на одном сайте, а управление транзакциями включает только локальный менеджер данных, работающий на одной машине. Местные транзакции легче осуществить.
Глобальное управление транзакциями требуется в распределенной вычислительной среде, где все ресурсы распределены по нескольким системам. В таком случае управление транзакциями должно осуществляться как на локальном, так и на глобальном уровнях. Распределенная или глобальная транзакция выполняется в нескольких системах, и ее выполнение требует координации между глобальной системой управления транзакциями и всеми локальными менеджерами данных всех участвующих систем.
Программный и декларативный
Spring поддерживает два типа управления транзакциями —
-
Программное управление транзакциями — это означает, что вы должны управлять транзакциями с помощью программирования. Это дает вам чрезвычайную гибкость, но это трудно поддерживать.
-
Декларативное управление транзакциями — это означает, что вы отделяете управление транзакциями от бизнес-кода. Вы используете только аннотации или конфигурацию на основе XML для управления транзакциями.
Программное управление транзакциями — это означает, что вы должны управлять транзакциями с помощью программирования. Это дает вам чрезвычайную гибкость, но это трудно поддерживать.
Декларативное управление транзакциями — это означает, что вы отделяете управление транзакциями от бизнес-кода. Вы используете только аннотации или конфигурацию на основе XML для управления транзакциями.
Декларативное управление транзакциями предпочтительнее программного управления транзакциями, хотя оно менее гибкое, чем программное управление транзакциями, которое позволяет вам контролировать транзакции с помощью кода. Но, как своего рода сквозная проблема, декларативное управление транзакциями может быть модульным с использованием подхода АОП. Spring поддерживает декларативное управление транзакциями через среду Spring AOP.
Абстракции весенней транзакции
Ключ к абстракции транзакции Spring определяется интерфейсом org.springframework.transaction.PlatformTransactionManager , который выглядит следующим образом:
public interface PlatformTransactionManager { TransactionStatus getTransaction(TransactionDefinition definition); throws TransactionException; void commit(TransactionStatus status) throws TransactionException; void rollback(TransactionStatus status) throws TransactionException; }
Sr.No | Метод и описание |
---|---|
1 |
TransactionStatus getTransaction (определение TransactionDefinition) Этот метод возвращает текущую активную транзакцию или создает новую в соответствии с заданным поведением распространения. |
2 |
void commit (статус TransactionStatus) Этот метод фиксирует данную транзакцию с учетом ее статуса. |
3 |
откат void (статус TransactionStatus) Этот метод выполняет откат данной транзакции. |
TransactionStatus getTransaction (определение TransactionDefinition)
Этот метод возвращает текущую активную транзакцию или создает новую в соответствии с заданным поведением распространения.
void commit (статус TransactionStatus)
Этот метод фиксирует данную транзакцию с учетом ее статуса.
откат void (статус TransactionStatus)
Этот метод выполняет откат данной транзакции.
TransactionDefinition является основным интерфейсом поддержки транзакций в Spring и определяется следующим образом:
public interface TransactionDefinition { int getPropagationBehavior(); int getIsolationLevel(); String getName(); int getTimeout(); boolean isReadOnly(); }
Sr.No | Метод и описание |
---|---|
1 |
int getPropagationBehavior () Этот метод возвращает поведение распространения. Spring предлагает все варианты распространения транзакций, знакомые по EJB CMT. |
2 |
int getIsolationLevel () Этот метод возвращает степень, в которой эта транзакция изолирована от работы других транзакций. |
3 |
Строка getName () Этот метод возвращает имя этой транзакции. |
4 |
int getTimeout () Этот метод возвращает время в секундах, в течение которого транзакция должна завершиться. |
5 |
логическое isReadOnly () Этот метод возвращает информацию о том, доступна ли транзакция только для чтения. |
int getPropagationBehavior ()
Этот метод возвращает поведение распространения. Spring предлагает все варианты распространения транзакций, знакомые по EJB CMT.
int getIsolationLevel ()
Этот метод возвращает степень, в которой эта транзакция изолирована от работы других транзакций.
Строка getName ()
Этот метод возвращает имя этой транзакции.
int getTimeout ()
Этот метод возвращает время в секундах, в течение которого транзакция должна завершиться.
логическое isReadOnly ()
Этот метод возвращает информацию о том, доступна ли транзакция только для чтения.
Ниже приведены возможные значения уровня изоляции:
Sr.No | Изоляция и описание |
---|---|
1 |
TransactionDefinition.ISOLATION_DEFAULT Это уровень изоляции по умолчанию. |
2 |
TransactionDefinition.ISOLATION_READ_COMMITTED Указывает, что грязные чтения предотвращены; могут произойти неповторяющиеся чтения и фантомные чтения. |
3 |
TransactionDefinition.ISOLATION_READ_UNCOMMITTED Указывает, что могут произойти грязные чтения, неповторяющиеся чтения и фантомные чтения. |
4 |
TransactionDefinition.ISOLATION_REPEATABLE_READ Указывает, что грязные чтения и неповторяющиеся чтения предотвращены; может произойти фантомное чтение. |
5 |
TransactionDefinition.ISOLATION_SERIALIZABLE Указывает, что грязные чтения, неповторяющиеся чтения и фантомные чтения предотвращены. |
TransactionDefinition.ISOLATION_DEFAULT
Это уровень изоляции по умолчанию.
TransactionDefinition.ISOLATION_READ_COMMITTED
Указывает, что грязные чтения предотвращены; могут произойти неповторяющиеся чтения и фантомные чтения.
TransactionDefinition.ISOLATION_READ_UNCOMMITTED
Указывает, что могут произойти грязные чтения, неповторяющиеся чтения и фантомные чтения.
TransactionDefinition.ISOLATION_REPEATABLE_READ
Указывает, что грязные чтения и неповторяющиеся чтения предотвращены; может произойти фантомное чтение.
TransactionDefinition.ISOLATION_SERIALIZABLE
Указывает, что грязные чтения, неповторяющиеся чтения и фантомные чтения предотвращены.
Ниже приведены возможные значения для типов распространения:
Sr.No. | Распространение и описание |
---|---|
1 |
TransactionDefinition.PROPAGATION_MANDATORY Поддерживает текущую транзакцию; выдает исключение, если текущей транзакции не существует. |
2 |
TransactionDefinition.PROPAGATION_NESTED Выполняется во вложенной транзакции, если текущая транзакция существует. |
3 |
TransactionDefinition.PROPAGATION_NEVER Не поддерживает текущую транзакцию; выдает исключение, если текущая транзакция существует. |
4 |
TransactionDefinition.PROPAGATION_NOT_SUPPORTED Не поддерживает текущую транзакцию; скорее всегда выполняйте нетранзакционно. |
5 |
TransactionDefinition.PROPAGATION_REQUIRED Поддерживает текущую транзакцию; создает новый, если ни один не существует. |
6 |
TransactionDefinition.PROPAGATION_REQUIRES_NEW Создает новую транзакцию, приостанавливая текущую транзакцию, если она существует. |
7 |
TransactionDefinition.PROPAGATION_SUPPORTS Поддерживает текущую транзакцию; выполняется без транзакций, если ни один не существует. |
8 |
TransactionDefinition.TIMEOUT_DEFAULT Использует время ожидания по умолчанию для базовой системы транзакций или не используется, если время ожидания не поддерживается. |
TransactionDefinition.PROPAGATION_MANDATORY
Поддерживает текущую транзакцию; выдает исключение, если текущей транзакции не существует.
TransactionDefinition.PROPAGATION_NESTED
Выполняется во вложенной транзакции, если текущая транзакция существует.
TransactionDefinition.PROPAGATION_NEVER
Не поддерживает текущую транзакцию; выдает исключение, если текущая транзакция существует.
TransactionDefinition.PROPAGATION_NOT_SUPPORTED
Не поддерживает текущую транзакцию; скорее всегда выполняйте нетранзакционно.
TransactionDefinition.PROPAGATION_REQUIRED
Поддерживает текущую транзакцию; создает новый, если ни один не существует.
TransactionDefinition.PROPAGATION_REQUIRES_NEW
Создает новую транзакцию, приостанавливая текущую транзакцию, если она существует.
TransactionDefinition.PROPAGATION_SUPPORTS
Поддерживает текущую транзакцию; выполняется без транзакций, если ни один не существует.
TransactionDefinition.TIMEOUT_DEFAULT
Использует время ожидания по умолчанию для базовой системы транзакций или не используется, если время ожидания не поддерживается.
Интерфейс TransactionStatus обеспечивает простой способ для транзакционного кода контролировать выполнение транзакции и запрашивать статус транзакции.
public interface TransactionStatus extends SavepointManager { boolean isNewTransaction(); boolean hasSavepoint(); void setRollbackOnly(); boolean isRollbackOnly(); boolean isCompleted(); }
Sr.No. | Метод и описание |
---|---|
1 |
логическое hasSavepoint () Этот метод возвращает, содержит ли эта транзакция внутреннюю точку сохранения, т. Е. Была ли она создана как вложенная транзакция на основе точки сохранения. |
2 |
логическое значение isCompleted () Этот метод возвращает, завершена ли эта транзакция, т. Е. Была ли она уже зафиксирована или откатана. |
3 |
логическое isNewTransaction () Этот метод возвращает true, если текущая транзакция является новой. |
4 |
логическое isRollbackOnly () Этот метод возвращает, была ли транзакция помечена как только для отката. |
5 |
void setRollbackOnly () Этот метод устанавливает транзакцию только для отката. |
логическое hasSavepoint ()
Этот метод возвращает, содержит ли эта транзакция внутреннюю точку сохранения, т. Е. Была ли она создана как вложенная транзакция на основе точки сохранения.
логическое значение isCompleted ()
Этот метод возвращает, завершена ли эта транзакция, т. Е. Была ли она уже зафиксирована или откатана.
логическое isNewTransaction ()
Этот метод возвращает true, если текущая транзакция является новой.
логическое isRollbackOnly ()
Этот метод возвращает, была ли транзакция помечена как только для отката.
void setRollbackOnly ()
Этот метод устанавливает транзакцию только для отката.
Spring — MVC Framework
Среда Spring Web MVC предоставляет архитектуру Model-View-Controller (MVC) и готовые компоненты, которые можно использовать для разработки гибких и слабосвязанных веб-приложений. Шаблон MVC приводит к разделению различных аспектов приложения (логика ввода, бизнес-логика и логика пользовательского интерфейса), обеспечивая при этом слабую связь между этими элементами.
-
Модель инкапсулирует данные приложения и в целом они состоят из POJO.
-
Представление отвечает за рендеринг данных модели и, в общем, генерирует вывод HTML, который может интерпретировать браузер клиента.
-
Контроллер отвечает за обработку пользовательских запросов и построение соответствующей модели и передает ее в представление для визуализации.
Модель инкапсулирует данные приложения и в целом они состоят из POJO.
Представление отвечает за рендеринг данных модели и, в общем, генерирует вывод HTML, который может интерпретировать браузер клиента.
Контроллер отвечает за обработку пользовательских запросов и построение соответствующей модели и передает ее в представление для визуализации.
ДиспетчерСервлет
Среда Spring Web Model-View-Controller (MVC) разработана на основе DispatcherServlet, который обрабатывает все HTTP-запросы и ответы. Рабочий процесс обработки запросов Spring Web MVC DispatcherServlet показан на следующей диаграмме:
Ниже приведена последовательность событий, соответствующая входящему HTTP-запросу в DispatcherServlet.
-
После получения HTTP-запроса DispatcherServlet обращается к HandlerMapping для вызова соответствующего контроллера .
-
Контроллер принимает запрос и вызывает соответствующие методы обслуживания на основе используемого метода GET или POST. Сервисный метод устанавливает данные модели на основе определенной бизнес-логики и возвращает имя представления в DispatcherServlet .
-
DispatcherServlet будет получать помощь от ViewResolver для получения определенного представления для запроса.
-
Как только представление завершено, DispatcherServlet передает данные модели в представление, которое в конечном итоге отображается в браузере.
После получения HTTP-запроса DispatcherServlet обращается к HandlerMapping для вызова соответствующего контроллера .
Контроллер принимает запрос и вызывает соответствующие методы обслуживания на основе используемого метода GET или POST. Сервисный метод устанавливает данные модели на основе определенной бизнес-логики и возвращает имя представления в DispatcherServlet .
DispatcherServlet будет получать помощь от ViewResolver для получения определенного представления для запроса.
Как только представление завершено, DispatcherServlet передает данные модели в представление, которое в конечном итоге отображается в браузере.
Все вышеупомянутые компоненты, то есть HandlerMapping, Controller и ViewResolver, являются частями WebApplicationContext w, который является расширением простого ApplicationContext с некоторыми дополнительными функциями, необходимыми для веб-приложений.
Требуемая конфигурация
Вам необходимо сопоставить запросы, которые вы хотите обработать с помощью DispatcherServlet , используя сопоставление URL-адресов в файле web.xml . Ниже приведен пример демонстрации объявления и сопоставления для примера HelloWeb DispatcherServlet:
<web-app id = "WebApp_ID" version = "2.4" xmlns = "http://java.sun.com/xml/ns/j2ee" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation = "http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <display-name>Spring MVC Application</display-name> <servlet> <servlet-name>HelloWeb</servlet-name> <servlet-class> org.springframework.web.servlet.DispatcherServlet </servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>HelloWeb</servlet-name> <url-pattern>*.jsp</url-pattern> </servlet-mapping> </web-app>
Файл web.xml будет храниться в каталоге WebContent / WEB-INF вашего веб-приложения. После инициализации HelloWeb DispatcherServlet платформа попытается загрузить контекст приложения из файла с именем [servlet-name] -servlet.xml, расположенного в каталоге WebContent / WEB-INF приложения. В этом случае наш файл будет HelloWebservlet.xml .
Затем тег <servlet-mapping> указывает, какие URL будут обрабатываться каким DispatcherServlet. Здесь все HTTP-запросы, заканчивающиеся на .jsp, будут обрабатываться HelloWeb DispatcherServlet.
Если вы не хотите использовать имя файла по умолчанию как [servlet-name] -servlet.xml и расположение по умолчанию как WebContent / WEB-INF , вы можете настроить это имя файла и местоположение, добавив прослушиватель сервлета ContextLoaderListener в свой файл web.xml следующим образом —
<web-app...> <!-------- DispatcherServlet definition goes here-----> .... <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/HelloWeb-servlet.xml</param-value> </context-param> <listener> <listener-class> org.springframework.web.context.ContextLoaderListener </listener-class> </listener> </web-app>
Теперь давайте проверим необходимую конфигурацию файла HelloWeb-servlet.xml , который находится в каталоге WebContent / WEB-INF вашего веб-приложения —
<beans xmlns = "http://www.springframework.org/schema/beans" xmlns:context = "http://www.springframework.org/schema/context" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation = "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <context:component-scan base-package = "com.tutorialspoint" /> <bean class = "org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name = "prefix" value = "/WEB-INF/jsp/" /> <property name = "suffix" value = ".jsp" /> </bean> </beans>
Ниже приведены важные моменты, касающиеся файла HelloWeb-servlet.xml.
-
Файл [servlet-name] -servlet.xml будет использоваться для создания определенных bean-компонентов, переопределяя определения любых bean-компонентов, определенных с таким же именем в глобальной области видимости.
-
Тег <context: component-scan …> будет использоваться для активации возможности сканирования аннотаций Spring MVC, которая позволяет использовать аннотации, такие как @Controller, @RequestMapping и т. Д.
-
InternalResourceViewResolver будет иметь правила, определенные для разрешения имен представлений. Согласно определенному выше правилу, логическое представление с именем hello делегируется реализации представления, расположенной в /WEB-INF/jsp/hello.jsp .
Файл [servlet-name] -servlet.xml будет использоваться для создания определенных bean-компонентов, переопределяя определения любых bean-компонентов, определенных с таким же именем в глобальной области видимости.
Тег <context: component-scan …> будет использоваться для активации возможности сканирования аннотаций Spring MVC, которая позволяет использовать аннотации, такие как @Controller, @RequestMapping и т. Д.
InternalResourceViewResolver будет иметь правила, определенные для разрешения имен представлений. Согласно определенному выше правилу, логическое представление с именем hello делегируется реализации представления, расположенной в /WEB-INF/jsp/hello.jsp .
Следующий раздел покажет вам, как создать ваши фактические компоненты, например, Controller, Model и View.
Определение контроллера
DispatcherServlet делегирует запрос контроллерам для выполнения специфической для него функциональности. Аннотация @Controller указывает, что определенный класс выполняет роль контроллера. Аннотация @RequestMapping используется для сопоставления URL либо с целым классом, либо с конкретным методом-обработчиком.
@Controller @RequestMapping("/hello") public class HelloController { @RequestMapping(method = RequestMethod.GET) public String printHello(ModelMap model) { model.addAttribute("message", "Hello Spring MVC Framework!"); return "hello"; } }
Аннотация @Controller определяет класс как контроллер Spring MVC. Здесь первое использование @RequestMapping указывает, что все методы обработки на этом контроллере относятся к пути / hello . Следующая аннотация @RequestMapping (method = RequestMethod.GET) используется для объявления метода printHello () в качестве метода службы контроллера по умолчанию для обработки HTTP-запроса GET. Вы можете определить другой метод для обработки любого запроса POST по тому же URL.
Вы можете написать приведенный выше контроллер в другой форме, где вы можете добавить дополнительные атрибуты в @RequestMapping следующим образом:
@Controller public class HelloController { @RequestMapping(value = "/hello", method = RequestMethod.GET) public String printHello(ModelMap model) { model.addAttribute("message", "Hello Spring MVC Framework!"); return "hello"; } }
Атрибут value указывает URL-адрес, с которым сопоставляется метод обработчика, а атрибут метода определяет метод службы для обработки HTTP-запроса GET. О контроллере, определенном выше, следует отметить следующие важные моменты:
-
Вы определите необходимую бизнес-логику внутри метода сервиса. Вы можете вызвать другой метод внутри этого метода согласно требованию.
-
На основе определенной бизнес-логики вы создадите модель в этом методе. Вы можете использовать различные атрибуты модели сеттера, и эти атрибуты будут доступны представлению для представления окончательного результата. В этом примере создается модель с атрибутом «сообщение».
-
Определенный метод службы может возвращать строку, которая содержит имя представления, которое будет использоваться для визуализации модели. Этот пример возвращает «привет» как логическое имя представления.
Вы определите необходимую бизнес-логику внутри метода сервиса. Вы можете вызвать другой метод внутри этого метода согласно требованию.
На основе определенной бизнес-логики вы создадите модель в этом методе. Вы можете использовать различные атрибуты модели сеттера, и эти атрибуты будут доступны представлению для представления окончательного результата. В этом примере создается модель с атрибутом «сообщение».
Определенный метод службы может возвращать строку, которая содержит имя представления, которое будет использоваться для визуализации модели. Этот пример возвращает «привет» как логическое имя представления.
Создание JSP-видов
Spring MVC поддерживает много типов представлений для различных технологий представления. К ним относятся — JSP, HTML, PDF, рабочие листы Excel, XML, шаблоны Velocity, XSLT, JSON, Atom и RSS-каналы, JasperReports и т. Д. Но чаще всего мы используем шаблоны JSP, написанные с использованием JSTL.
Давайте напишем простое приветственное представление в /WEB-INF/hello/hello.jsp —
<html> <head> <title>Hello Spring MVC</title> </head> <body> <h2>${message}</h2> </body> </html>
Здесь $ {message} — это атрибут, который мы установили внутри контроллера. Вы можете иметь несколько атрибутов для отображения внутри вашего представления.
Spring Web MVC Framework Примеры
Основываясь на вышеизложенных концепциях, давайте проверим несколько важных примеров, которые помогут вам в создании веб-приложений Spring —
Sr.No. | Пример и описание |
---|---|
1 | Spring MVC Пример Hello World
В этом примере объясняется, как написать простое приложение Spring Web Hello World. |
2 | Spring MVC Пример обработки форм
В этом примере объясняется, как написать веб-приложение Spring с использованием HTML-форм для отправки данных в контроллер и отображения обработанного результата. |
3 | Пример перенаправления весенней страницы
Узнайте, как использовать функциональность перенаправления страниц в Spring MVC Framework. |
4 | Пример Spring Static Pages
Узнайте, как получить доступ к статическим страницам вместе с динамическими страницами в Spring MVC Framework. |
5 | Пример обработки исключений Spring
Узнайте, как обрабатывать исключения в Spring MVC Framework. |
В этом примере объясняется, как написать простое приложение Spring Web Hello World.
В этом примере объясняется, как написать веб-приложение Spring с использованием HTML-форм для отправки данных в контроллер и отображения обработанного результата.
Узнайте, как использовать функциональность перенаправления страниц в Spring MVC Framework.
Узнайте, как получить доступ к статическим страницам вместе с динамическими страницами в Spring MVC Framework.
Узнайте, как обрабатывать исключения в Spring MVC Framework.
Весна — Вход с Log4J
Это очень простая в использовании функция Log4J в приложениях Spring. Следующий пример проведет вас через простые шаги, чтобы объяснить простую интеграцию между Log4J и Spring.
Мы предполагаем, что на вашем компьютере уже установлен log4J . Если у вас его нет, вы можете скачать его с https://logging.apache.org/ и просто распаковать архив в любую папку. Мы будем использовать только log4j-xyzjar в нашем проекте.
Далее, давайте создадим рабочую среду Eclipse и предпримем следующие шаги для разработки веб-приложения на основе динамических форм с использованием Spring Web Framework:
меры | Описание |
---|---|
1 | Создайте проект с именем SpringExample и создайте пакет com.tutorialspoint в папке src в созданном проекте. |
2 | Добавьте необходимые библиотеки Spring с помощью параметра « Добавить внешние JAR-файлы», как описано в главе « Пример Hello World» . |
3 | Добавьте библиотеку log4j и log4j-xyzjar в свой проект, используя Добавить внешние JAR-файлы . |
4 | Создайте классы Java HelloWorld и MainApp в пакете com.tutorialspoint . |
5 | Создайте файл конфигурации Beans Beans.xml в папке src . |
6 | Создайте файл конфигурации log4J log4j.properties в папке src . |
7 | Последний шаг — создать содержимое всех файлов Java и файла конфигурации Bean и запустить приложение, как описано ниже. |
Вот содержимое файла HelloWorld.java
package com.tutorialspoint; public class HelloWorld { private String message; public void setMessage(String message){ this.message = message; } public void getMessage() { System.out.println("Your Message : " + message); } }
Ниже приводится содержание второго файла MainApp.java
package com.tutorialspoint; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.apache.log4j.Logger; public class MainApp { static Logger log = Logger.getLogger(MainApp.class.getName()); public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml"); log.info("Going to create HelloWord Obj"); HelloWorld obj = (HelloWorld) context.getBean("helloWorld"); obj.getMessage(); log.info("Exiting the program"); } }
Вы можете генерировать сообщения об отладке и ошибках аналогично тому, как мы генерировали информационные сообщения. Теперь давайте посмотрим содержимое файла Beans.xml
<?xml version = "1.0" encoding = "UTF-8"?> <beans xmlns = "http://www.springframework.org/schema/beans" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation = "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <bean id = "helloWorld" class = "com.tutorialspoint.HelloWorld"> <property name = "message" value = "Hello World!"/> </bean> </beans>
Ниже приводится содержание log4j.properties, которое определяет стандартные правила, необходимые для Log4J для создания сообщений журнала
# Define the root logger with appender file log4j.rootLogger = DEBUG, FILE # Define the file appender log4j.appender.FILE=org.apache.log4j.FileAppender # Set the name of the file log4j.appender.FILE.File=C:\\log.out # Set the immediate flush to true (default) log4j.appender.FILE.ImmediateFlush=true # Set the threshold to debug mode log4j.appender.FILE.Threshold=debug # Set the append to false, overwrite log4j.appender.FILE.Append=false # Define the layout for file appender log4j.appender.FILE.layout=org.apache.log4j.PatternLayout log4j.appender.FILE.layout.conversionPattern=%m%n
Как только вы закончили создавать файлы конфигурации исходного кода и bean-компонента, давайте запустим приложение. Если с вашим приложением все в порядке, в консоли Eclipse будет напечатано следующее сообщение:
Your Message : Hello World!
Если вы проверите свой диск C: \\, то вы должны найти свой файл журнала log.out с различными сообщениями журнала, например, как показано ниже:
<!-- initialization log messages --> Going to create HelloWord Obj Returning cached instance of singleton bean 'helloWorld' Exiting the program
Jakarta Commons Logging (JCL) API
В качестве альтернативы вы можете использовать API Jakarta Commons Logging (JCL) для создания журнала в приложении Spring. JCL можно загрузить с https://jakarta.apache.org/commons/logging/ . Единственный файл, который нам технически нужен из этого пакета, это файл commons-logging-xyzjar , который нужно поместить в ваш путь к классу так же, как вы поместили log4j-xyzjar в приведенном выше примере.
Для использования функции ведения журнала вам необходим объект org.apache.commons.logging.Log, а затем вы можете вызвать один из следующих методов в соответствии с вашим требованием:
- фатальный (объект сообщения)
- ошибка (объектное сообщение)
- предупреждение (объект сообщения)
- info (объект сообщения)
- отладка (объект сообщения)
- трассировка (объектное сообщение)
Ниже приводится замена MainApp.java, которая использует JCL API.
package com.tutorialspoint; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.apache.commons.logging. Log; import org.apache.commons.logging. LogFactory; public class MainApp { static Log log = LogFactory.getLog(MainApp.class.getName()); public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml"); log.info("Going to create HelloWord Obj"); HelloWorld obj = (HelloWorld) context.getBean("helloWorld"); obj.getMessage(); log.info("Exiting the program"); } }
Вы должны убедиться, что вы включили файл commons-logging-xyzjar в свой проект, прежде чем компилировать и запускать программу.
Теперь, оставив остальную часть конфигурации и содержимого без изменений в приведенном выше примере, если вы скомпилируете и запустите свое приложение, вы получите результат, аналогичный тому, который вы получили, используя Log4J API.