Весна - Краткое руководство

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, просто, потому что код, зависящий от среды, перемещен в эту структуру. Кроме того, благодаря использованию POJO JavaBeanstyle становится проще использовать внедрение зависимостей для внедрения тестовых данных.

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

  • Spring предоставляет удобный API для преобразования исключений, связанных с конкретной технологией (например, вызванных JDBC, Hibernate или JDO) в согласованные, непроверенные исключения.

  • Легкие контейнеры IoC обычно бывают легкими, особенно по сравнению, например, с контейнерами EJB. Это полезно для разработки и развертывания приложений на компьютерах с ограниченными ресурсами памяти и ЦП.

  • Spring предоставляет согласованный интерфейс управления транзакциями, который может масштабироваться до локальной транзакции (например, с использованием одной базы данных) и масштабироваться до глобальных транзакций (например, с использованием JTA).

Внедрение зависимостей (DI)

Технология, с которой больше всего ассоциируется Spring, - это Dependency Injection (DI)аромат инверсии контроля. ВInversion of Control (IoC)это общее понятие, и его можно выразить по-разному. Внедрение зависимостей - лишь один конкретный пример инверсии управления.

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

Что такое внедрение зависимостей? Давайте рассмотрим эти два слова по отдельности. Здесь часть зависимости переводится в ассоциацию между двумя классами. Например, класс A зависит от класса B. Теперь давайте посмотрим на вторую часть, инъекцию. Все это означает, что класс B будет введен IoC в класс A.

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

Аспектно-ориентированное программирование (АОП)

Одним из ключевых компонентов Spring является Aspect Oriented Programming (AOP)фреймворк. Функции, охватывающие несколько точек приложения, называютсяcross-cutting concernsи эти сквозные проблемы концептуально отделены от бизнес-логики приложения. Существуют различные общие хорошие примеры аспектов, включая ведение журнала, декларативные транзакции, безопасность, кеширование и т. Д.

Ключевой единицей модульности в ООП является класс, тогда как в АОП единицей модульности является аспект. DI помогает отделить объекты приложения друг от друга, в то время как AOP помогает отделить сквозные проблемы от объектов, на которые они влияют.

Модуль AOP Spring Framework предоставляет реализацию аспектно-ориентированного программирования, позволяющую определять методы-перехватчики и pointcuts для четкого разделения кода, реализующего функции, которые должны быть разделены. Мы обсудим больше о концепциях Spring AOP в отдельной главе.

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

Spring Framework предоставляет около 20 модулей, которые можно использовать в зависимости от требований приложения.

Основной контейнер

Основной контейнер состоит из модулей Core, Beans, Context и Expression Language, подробности которых следующие:

  • В 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 Модуль предоставляет уровень абстракции, который поддерживает реализации сопоставления Object / XML для JAXB, Castor, XMLBeans, JiBX и XStream.

  • Служба обмена сообщениями Java JMS Модуль содержит функции для создания и использования сообщений.

  • В Transaction модуль поддерживает программное и декларативное управление транзакциями для классов, реализующих специальные интерфейсы, и для всех ваших POJO.

Интернет

Веб-уровень состоит из модулей Web, Web-MVC, Web-Socket и Web-Portlet, детали которых следующие:

  • В Web Модуль предоставляет базовые функции интеграции, ориентированные на веб-интерфейс, такие как функция загрузки нескольких файлов и инициализация контейнера IoC с использованием прослушивателей сервлетов и контекста веб-приложения.

  • В Web-MVC Модуль содержит реализацию Spring Model-View-Controller (MVC) для веб-приложений.

  • В Web-Socket модуль обеспечивает поддержку основанной на WebSocket двусторонней связи между клиентом и сервером в веб-приложениях.

  • В Web-Portlet Модуль предоставляет реализацию MVC для использования в среде портлетов и отражает функциональность модуля Web-Servlet.

Разное

Есть несколько других важных модулей, таких как АОП, аспекты, инструменты, веб-модули и модули тестирования, детали которых следующие:

  • В AOP Модуль обеспечивает реализацию аспектно-ориентированного программирования, позволяющую вам определять методы-перехватчики и pointcuts для четкого разделения кода, реализующего функциональные возможности, которые должны быть разделены.

  • В Aspects Модуль обеспечивает интеграцию с AspectJ, который снова является мощным и зрелым фреймворком АОП.

  • В Instrumentation Модуль обеспечивает поддержку инструментария классов и реализации загрузчика классов для использования на определенных серверах приложений.

  • В MessagingМодуль обеспечивает поддержку 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

Вы можете скачать последнюю версию Apache Commons Logging API с 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 framework из https://repo.spring.io/release/org/springframework/spring.

  • Во время разработки этого руководства, spring-framework-4.1.6.RELEASE-dist.zipбыл загружен на машину с Windows. После того, как загруженный файл был распакован, он дает следующую структуру каталогов внутри E: \ spring.

Вы найдете все библиотеки Spring в каталоге E:\spring\libs. Убедитесь, что вы правильно установили переменную CLASSPATH в этом каталоге, иначе вы столкнетесь с проблемой при запуске вашего приложения. Если вы используете Eclipse, то устанавливать CLASSPATH не обязательно, потому что все настройки будут выполняться через Eclipse.

Как только вы закончите с этим последним шагом, вы готовы перейти к первому примеру Spring в следующей главе.

Давайте начнем реальное программирование со Spring Framework. Прежде чем вы начнете писать свой первый пример с использованием среды Spring, вы должны убедиться, что вы правильно настроили среду Spring, как описано в главе « Spring - Настройка среды» . Мы также предполагаем, что у вас есть кое-какие практические знания о Eclipse IDE.

Теперь приступим к написанию простого приложения Spring, которое будет печатать «Hello World!». или любое другое сообщение, основанное на конфигурации, выполненной в файле конфигурации Spring Beans.

Шаг 1 - Создайте проект Java

Первый шаг - создать простой Java-проект с использованием Eclipse IDE. Следуйте вариантуFile → New → Project и, наконец, выберите Java Projectмастер из списка мастеров. Теперь назовите свой проект какHelloSpring используя окно мастера следующим образом -

Как только ваш проект будет успешно создан, у вас будет следующий контент в вашем Project Explorer -

Шаг 2 - Добавьте необходимые библиотеки

В качестве второго шага добавим в наш проект Spring Framework и библиотеки Common Logging API. Для этого щелкните правой кнопкой мыши название вашего проекта.HelloSpring а затем выполните следующую опцию, доступную в контекстном меню - Build Path → Configure Build Path чтобы отобразить окно пути сборки Java следующим образом -

Теперь используйте Add External JARs кнопка доступна под Libraries Вкладка, чтобы добавить следующие основные JAR из каталогов установки Spring Framework и Common Logging:

  • commons-logging-1.1.1

  • spring-aop-4.1.6.RELEASE

  • spring-aspects-4.1.6.RELEASE

  • spring-beans-4.1.6.RELEASE

  • spring-context-4.1.6.RELEASE

  • spring-context-support-4.1.6.RELEASE

  • spring-core-4.1.6.RELEASE

  • spring-expression-4.1.6.RELEASE

  • spring-instrument-4.1.6.RELEASE

  • spring-instrument-tomcat-4.1.6.RELEASE

  • spring-jdbc-4.1.6.RELEASE

  • spring-jms-4.1.6.RELEASE

  • spring-messaging-4.1.6.RELEASE

  • spring-orm-4.1.6.RELEASE

  • spring-oxm-4.1.6.RELEASE

  • spring-test-4.1.6.RELEASE

  • spring-tx-4.1.6.RELEASE

  • spring-web-4.1.6.RELEASE

  • spring-webmvc-4.1.6.RELEASE

  • spring-webmvc-portlet-4.1.6.RELEASE

  • spring-websocket-4.1.6.RELEASE

Шаг 3 - Создание исходных файлов

Теперь давайте создадим реальные исходные файлы под HelloSpringпроект. Сначала нам нужно создать пакет под названиемcom.tutorialspoint. Для этого щелкните правой кнопкой мыши наsrc в разделе проводника пакетов и следуйте опции - New → Package.

Далее мы создадим 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 загружает файл конфигурации beans и, в конечном итоге, на основе предоставленного API, он заботится о создании и инициализации всех объектов, то есть bean-компонентов, упомянутых в файле конфигурации.

  • Второй шаг используется для получения необходимого 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 активной и используйте либоRun вариант, доступный в Eclipse IDE, или используйте Ctrl + F11 скомпилировать и запустить ваш MainAppприменение. Если с вашим приложением все в порядке, в консоли Eclipse IDE будет выведено следующее сообщение:

Your Message : Hello World!

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

Контейнер Spring лежит в основе Spring Framework. Контейнер будет создавать объекты, связывать их вместе, настраивать и управлять их полным жизненным циклом от создания до уничтожения. Контейнер Spring использует DI для управления компонентами, составляющими приложение. Эти объекты называются Spring Beans, о которых мы поговорим в следующей главе.

Контейнер получает инструкции о том, какие объекты создавать, настраивать и собирать, читая предоставленные метаданные конфигурации. Метаданные конфигурации могут быть представлены в виде XML, аннотаций Java или кода Java. На следующей диаграмме представлено общее представление о том, как работает Spring. Контейнер Spring IoC использует классы Java POJO и метаданные конфигурации для создания полностью сконфигурированной и исполняемой системы или приложения.

Spring предоставляет следующие два различных типа контейнеров.

Sr.No. Контейнер и описание
1 Весенний контейнер BeanFactory

Это простейший контейнер, обеспечивающий базовую поддержку DI и определяемый интерфейсом org.springframework.beans.factory.BeanFactory . BeanFactory и связанные с ним интерфейсы, такие как BeanFactoryAware, InitializingBean, DisposableBean, все еще присутствуют в Spring с целью обратной совместимости с большим количеством сторонних фреймворков, которые интегрируются со Spring.

2 Контейнер Spring ApplicationContext

Этот контейнер добавляет дополнительные корпоративные функции, такие как возможность разрешать текстовые сообщения из файла свойств и возможность публиковать события приложения для заинтересованных слушателей событий. Этот контейнер определяется интерфейсом org.springframework.context.ApplicationContext .

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

Объекты, образующие основу вашего приложения и управляемые контейнером Spring IoC, называются beans. Бин - это объект, который создается, собирается и иным образом управляется контейнером Spring IoC. Эти bean-компоненты создаются с использованием метаданных конфигурации, которые вы передаете контейнеру. Например, в виде определений XML <bean />, которые вы уже видели в предыдущих главах.

Определение компонента содержит информацию, называемую configuration metadata, который необходим для того, чтобы контейнер знал следующее:

  • Как создать боб
  • Подробности жизненного цикла бина
  • Зависимости бина

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

Sr.No. Свойства и описание
1

class

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

2

name

Этот атрибут однозначно определяет идентификатор компонента. В метаданных конфигурации на основе XML вы используете атрибуты id и / или name для определения идентификатора (ов) bean-компонента.

3

scope

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

4

constructor-arg

Это используется для внедрения зависимостей и будет обсуждаться в следующих главах.

5

properties

Это используется для внедрения зависимостей и будет обсуждаться в следующих главах.

6

autowiring mode

Это используется для внедрения зависимостей и будет обсуждаться в следующих главах.

7

lazy-initialization mode

Ленивый инициализированный компонент сообщает контейнеру IoC создать экземпляр компонента при первом запросе, а не при запуске.

8

initialization method

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

9

destruction method

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

Метаданные конфигурации 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, чтобы понять, как определять, настраивать и создавать Spring Beans.

Мы обсудим конфигурацию на основе аннотаций в отдельной главе. Это намеренно обсуждается в отдельной главе, так как мы хотим, чтобы вы усвоили несколько других важных концепций Spring, прежде чем начинать программировать с помощью Spring Dependency Injection с аннотациями.

При определении <bean> у вас есть возможность объявить область для этого bean-компонента. Например, чтобы заставить Spring создавать новый экземпляр компонента каждый раз, когда он необходим, вы должны объявить атрибут области действия компонента какprototype. Точно так же, если вы хотите, чтобы Spring возвращал один и тот же экземпляр компонента каждый раз, когда он необходим, вам следует объявить атрибут области действия компонента какsingleton.

Spring Framework поддерживает следующие пять областей, три из которых доступны только в том случае, если вы используете ApplicationContext, поддерживающий веб.

Sr.No. Объем и описание
1

singleton

Это ограничивает определение компонента одним экземпляром для каждого контейнера Spring IoC (по умолчанию).

2

prototype

Это ограничивает одно определение bean-объекта любым количеством экземпляров объекта.

3

request

Это ограничивает определение компонента HTTP-запросом. Допустимо только в контексте Spring ApplicationContext, поддерживающего веб.

4

session

Это ограничивает определение bean-компонента сеансом HTTP. Допустимо только в контексте Spring ApplicationContext, поддерживающего веб.
5

global-session

Это ограничивает определение компонента глобальным сеансом HTTP. Допустимо только в контексте Spring ApplicationContext, поддерживающего веб.

В этой главе мы обсудим первые две области действия, а остальные три будут обсуждены, когда мы будем обсуждать веб-ориентированный Spring ApplicationContext.

Одноэлементный объем

Если для области задано значение singleton, контейнер Spring IoC создает ровно один экземпляр объекта, определенного этим определением bean-компонента. Этот единственный экземпляр хранится в кеше таких одноэлементных bean-компонентов, и все последующие запросы и ссылки для этого именованного bean-компонента возвращают кэшированный объект.

Область по умолчанию всегда одноэлементная. Однако, когда вам нужен один и только один экземпляр компонента, вы можете установитьscope собственность singleton в файле конфигурации bean-компонента, как показано в следующем фрагменте кода -

<!-- 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», как описано в главе « Пример Spring Hello World» .
3 Создайте классы Java HelloWorld и MainApp в пакете com.tutorialspoint .
4 Создайте файл конфигурации Beans Beans.xml подsrc папка.
5 Последний шаг - создать содержимое всех файлов Java и файла конфигурации компонента и запустить приложение, как описано ниже.

Вот содержание 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

Объем прототипа

Если для области задано значение prototype, контейнер Spring IoC создает новый экземпляр объекта bean-компонента каждый раз, когда делается запрос для этого конкретного bean-компонента. Как правило, используйте область прототипа для всех bean-компонентов с полным состоянием и одноэлементную область для bean-компонентов без состояния.

Чтобы определить область действия прототипа, вы можете установить scope собственность prototype в файле конфигурации bean-компонента, как показано в следующем фрагменте кода -

<!-- A bean definition with prototype scope -->
<bean id = "..." class = "..." scope = "prototype">
   <!-- collaborators and configuration for this bean go here -->
</bean>

пример

Разрешите нам иметь рабочую среду Eclipse IDE и выполнить следующие шаги, чтобы создать приложение Spring:

Шаги Описание
1 Создайте проект с именем SpringExample и создайте пакет com.tutorialspoint подsrc папку в созданном проекте.
2 Добавьте необходимые библиотеки Spring с помощью опции « Добавить внешние JAR», как описано в главе « Пример Spring Hello World» .
3 Создайте классы Java HelloWorld и MainApp в пакете com.tutorialspoint .
4 Создайте файл конфигурации Beans Beans.xml подsrc папка.
5 Последний шаг - создать содержимое всех файлов Java и файла конфигурации компонента и запустить приложение, как описано ниже.

Вот содержание 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 и его уничтожением, в этой главе будут обсуждаться только два важных метода обратного вызова жизненного цикла bean, которые требуются во время инициализации bean и его уничтожения.

Чтобы определить настройку и удаление компонента, мы просто объявляем <bean> с помощью initmethod и / или destroy-methodпараметры. Атрибут init-method указывает метод, который должен быть вызван в компоненте сразу после создания экземпляра. Точно так же destroymethod определяет метод, который вызывается непосредственно перед удалением bean-компонента из контейнера.

Обратные вызовы инициализации

Интерфейс 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», как описано в главе « Пример Spring Hello World» .
3 Создайте классы Java HelloWorld и MainApp в пакете com.tutorialspoint .
4 Создайте файл конфигурации Beans Beans.xml подsrc папка.
5 Последний шаг - создать содержимое всех файлов Java и файла конфигурации компонента и запустить приложение, как описано ниже.

Вот содержание 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файл. Здесь нужно зарегистрировать хук выключенияregisterShutdownHook(), объявленный в классе 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.

Методы инициализации и уничтожения по умолчанию

Если у вас слишком много bean-компонентов с одинаковыми методами инициализации и / или уничтожения, вам не нужно объявлять init-method и destroy-methodна каждом отдельном бобе. Вместо этого платформа обеспечивает гибкость для настройки такой ситуации с помощью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>

В BeanPostProcessor interface определяет методы обратного вызова, которые вы можете реализовать для предоставления вашей собственной логики создания экземпляров, логики разрешения зависимостей и т. д. Вы также можете реализовать некоторую пользовательскую логику после того, как контейнер Spring завершит создание экземпляра, настройку и инициализацию bean-компонента, подключив одну или несколько реализаций BeanPostProcessor .

Вы можете настроить несколько интерфейсов BeanPostProcessor, и вы можете контролировать порядок, в котором эти интерфейсы BeanPostProcessor выполняются, установив параметр order свойство при условии, что BeanPostProcessor реализует Ordered интерфейс.

BeanPostProcessors работают с экземплярами bean (или объекта), что означает, что контейнер Spring IoC создает экземпляр bean-компонента, а затем интерфейсы BeanPostProcessor выполняют свою работу.

An ApplicationContext автоматически обнаруживает любые bean-компоненты, которые определены с реализацией BeanPostProcessor интерфейс и регистрирует эти bean-компоненты как постпроцессоры, которые затем соответствующим образом вызываются контейнером при создании bean-компонента.

пример

В следующих примерах показано, как писать, регистрировать и использовать BeanPostProcessors в контексте ApplicationContext.

Разрешите нам иметь рабочую среду разработки Eclipse и предпринять следующие шаги для создания приложения Spring:

Шаги Описание
1 Создайте проект с именем SpringExample и создайте пакет com.tutorialspoint подsrc папку в созданном проекте.
2 Добавьте необходимые библиотеки Spring с помощью опции « Добавить внешние JAR», как описано в главе « Пример Spring Hello World» .
3 Создайте классы Java HelloWorld , InitHelloWorld и MainApp в пакете com.tutorialspoint .
4 Создайте файл конфигурации Beans Beans.xml подsrc папка.
5 Последний шаг - создать содержимое всех файлов Java и файла конфигурации компонента и запустить приложение, как описано ниже.

Вот содержание 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, который печатает имя bean-компонента до и после инициализации любого bean-компонента. Вы можете реализовать более сложную логику до и после инициализации bean-компонента, потому что у вас есть доступ к объекту bean-компонента внутри обоих методов постпроцессора.

Вот содержание 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файл. Здесь нужно зарегистрировать хук выключенияregisterShutdownHook(), объявленный в классе 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.

Определение bean-компонента может содержать много информации о конфигурации, включая аргументы конструктора, значения свойств и специфичную для контейнера информацию, такую ​​как метод инициализации, имя статического фабричного метода и т. Д.

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

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

Когда вы используете метаданные конфигурации на основе XML, вы указываете определение дочернего компонента с помощью parent атрибут, определяющий родительский компонент как значение этого атрибута.

пример

Разрешите нам иметь рабочую среду разработки Eclipse и предпринять следующие шаги для создания приложения Spring:

Шаги Описание
1 Создайте проект с именем SpringExample и создайте пакет com.tutorialspoint подsrc папку в созданном проекте.
2 Добавьте необходимые библиотеки Spring с помощью опции « Добавить внешние JAR», как описано в главе « Пример Spring Hello World» .
3 Создайте классы Java HelloWorld , HelloIndia и MainApp в пакете com.tutorialspoint .
4 Создайте файл конфигурации Beans Beans.xml подsrc папка.
5 Последний шаг - создать содержимое всех файлов Java и файла конфигурации компонента и запустить приложение, как описано ниже.

Ниже приведен файл конфигурации Beans.xmlгде мы определили bean-компонент helloWorld, который имеет два свойства: message1 и message2 . Следующий bean-компонент helloIndia был определен как потомок bean-компонента helloWorld с помощьюparentатрибут. Дочерний bean-компонент наследует свойство 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", но оно было передано из-за наследования определения Bean-компонента.

Шаблон определения компонента

Вы можете создать шаблон определения компонента, который может использоваться другими определениями дочернего компонента без особых усилий. При определении шаблона определения компонента не следует указыватьclass атрибут и должен указать abstract атрибут и должен указать абстрактный атрибут со значением 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>

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

Каждое приложение на основе 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 через Class Constructor. Таким образом, поток управления был «инвертирован» внедрением зависимостей (DI), потому что вы фактически делегировали зависимости какой-то внешней системе.

Второй метод внедрения зависимости - через Setter Methodsкласса TextEditor, в котором мы создадим экземпляр SpellChecker. Этот экземпляр будет использоваться для вызова методов установки для инициализации свойств TextEditor.

Таким образом, DI существует в двух основных вариантах, и в следующих двух подразделах мы рассмотрим оба из них с примерами:

Sr.No. Тип и описание внедрения зависимости
1 Внедрение зависимостей на основе конструктора

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

2 Внедрение зависимостей на основе сеттера

DI на основе установщика выполняется контейнером, вызывающим методы установщика в ваших bean-компонентах после вызова конструктора без аргументов или статического фабричного метода без аргументов для создания экземпляра вашего bean-компонента.

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

Код чище с принципом DI, и разъединение более эффективно, когда объектам предоставляются их зависимости. Объект не ищет свои зависимости и не знает местоположение или класс зависимостей, скорее, обо всем позаботится Spring Framework.

Как вы знаете, внутренние классы Java определены в рамках других классов, аналогично inner beans- это бины, которые определены в рамках другого бина. Таким образом, элемент <bean /> внутри элементов <property /> или <constructor-arg /> называется внутренним 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">

   <bean id = "outerBean" class = "...">
      <property name = "target">
         <bean id = "innerBean" class = "..."/>
      </property>
   </bean>

</beans>

пример

Разрешите нам иметь рабочую среду Eclipse IDE и выполнить следующие шаги, чтобы создать приложение Spring:

Шаги Описание
1 Создайте проект с именем SpringExample и создайте пакет com.tutorialspoint подsrc папку в созданном проекте.
2 Добавьте необходимые библиотеки Spring с помощью опции « Добавить внешние JAR», как описано в главе « Пример Spring Hello World» .
3 Создайте классы Java TextEditor , SpellChecker и MainApp в пакете com.tutorialspoint .
4 Создайте файл конфигурации Beans Beans.xml подsrc папка.
5 Последний шаг - создать содержимое всех файлов Java и файла конфигурации компонента и запустить приложение, как описано ниже.

Вот содержание 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 который имеет конфигурацию для инъекции на основе установщика, но использует inner beans -

<?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.

Вы видели, как настроить примитивный тип данных с помощью value ссылки на атрибуты и объекты с использованием refатрибут тега <property> в вашем файле конфигурации Bean. Оба случая имеют дело с передачей сингулярного значения компоненту.

А что, если вы хотите передать множественные значения, такие как типы Java Collection, такие как List, Set, Map и Properties. Чтобы справиться с ситуацией, Spring предлагает четыре типа элементов конфигурации коллекции, а именно:

Старший Нет Элемент и описание
1

<list>

Это помогает в подключении, то есть вводе списка значений, позволяющем дублировать.

2

<set>

Это помогает связать набор значений, но без дубликатов.

3

<map>

Это можно использовать для добавления коллекции пар имя-значение, где имя и значение могут быть любого типа.

4

<props>

Это можно использовать для вставки коллекции пар имя-значение, где имя и значение являются строками.

Вы можете использовать <list> или <set> для подключения любой реализации java.util.Collection или array.

Вы столкнетесь с двумя ситуациями: (а) передача прямых значений коллекции и (б) передача ссылки на bean-компонент в качестве одного из элементов коллекции.

пример

Разрешите нам иметь рабочую среду разработки Eclipse и предпринять следующие шаги для создания приложения Spring:

Шаги Описание
1 Создайте проект с именем SpringExample и создайте пакет com.tutorialspoint подsrc папку в созданном проекте.
2 Добавьте необходимые библиотеки Spring с помощью опции « Добавить внешние JAR», как описано в главе « Пример Spring Hello World» .
3 Создайте классы Java JavaCollection и MainApp в пакете com.tutorialspoint .
4 Создайте файл конфигурации Beans Beans.xml подsrc папка.
5 Последний шаг - создать содержимое всех файлов Java и файла конфигурации компонента и запустить приложение, как описано ниже.

Вот содержание 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}

Внедрение ссылок на бин

Следующее определение Bean поможет вам понять, как внедрить ссылки на 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">

   <!-- 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> и вставлять <bean> с помощью элементов <constructor-arg> и <property> в файле конфигурации XML.

Контейнер Spring может autowire отношения между взаимодействующими компонентами без использования элементов <constructor-arg> и <property>, что помогает сократить объем XML-конфигурации, которую вы пишете для большого приложения на основе Spring.

Режимы автоматического подключения

Ниже приведены режимы автоматического подключения, которые можно использовать для указания контейнеру Spring использовать автоматическое подключение для внедрения зависимостей. Вы используете атрибут autowire элемента <bean />, чтобы указатьautowire режим для определения bean.

Старший Нет Режим и описание
1 no

Это настройка по умолчанию, что означает отсутствие автоматического подключения, и вы должны использовать явную ссылку на компонент для подключения. Вам нечего делать с этой проводкой. Это то, что вы уже видели в главе «Внедрение зависимостей».

2 по имени

Автоподключение по названию собственности. Контейнер Spring смотрит на свойства bean-компонентов, для которых атрибут autowire установлен на byName в файле конфигурации XML. Затем он пытается сопоставить и связать свои свойства с bean-компонентами, определенными с теми же именами в файле конфигурации.

3 byType

Автономное подключение по типу данных свойства. Контейнер Spring смотрит на свойства bean-компонентов, для которых атрибут autowire установлен на byType в файле конфигурации XML. Затем он пытается сопоставить и подключить свойство, если егоtypeсовпадает точно с одним из имен beans в файле конфигурации. Если существует более одного такого bean-компонента, генерируется фатальное исключение.

4 constructor

Similar to byType, but type applies to constructor arguments. If there is not exactly one bean of the constructor argument type in the container, a fatal error is raised.

5 autodetect

Spring first tries to wire using autowire by constructor, if it does not work, Spring tries to autowire by byType.

You can use byType or constructor autowiring mode to wire arrays and other typed-collections.

Limitations with autowiring

Autowiring works best when it is used consistently across a project. If autowiring is not used in general, it might be confusing for developers to use it to wire only one or two bean definitions. Though, autowiring can significantly reduce the need to specify properties or constructor arguments but you should consider the limitations and disadvantages of autowiring before using them.

Sr.No. Limitations & Description
1

Overriding possibility

You can still specify dependencies using <constructor-arg> and <property> settings which will always override autowiring.

2

Primitive data types

You cannot autowire so-called simple properties such as primitives, Strings, and Classes.

3

Confusing nature

Autowiring is less exact than explicit wiring, so if possible prefer using explict wiring.

Starting from Spring 2.5 it became possible to configure the dependency injection using annotations. So instead of using XML to describe a bean wiring, you can move the bean configuration into the component class itself by using annotations on the relevant class, method, or field declaration.

Annotation injection is performed before XML injection. Thus, the latter configuration will override the former for properties wired through both approaches.

Annotation wiring is not turned on in the Spring container by default. So, before we can use annotation-based wiring, we will need to enable it in our Spring configuration file. So consider the following configuration file in case you want to use any annotation in your Spring application.

<?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>

Once <context:annotation-config/> is configured, you can start annotating your code to indicate that Spring should automatically wire values into properties, methods, and constructors. Let us look at a few important annotations to understand how they work −

Sr.No. Annotation & Description
1 @Required

The @Required annotation applies to bean property setter methods.

2 @Autowired

The @Autowired annotation can apply to bean property setter methods, non-setter methods, constructor and properties.

3 @Qualifier

The @Qualifier annotation along with @Autowired can be used to remove the confusion by specifiying which exact bean will be wired.

4 JSR-250 Annotations

Spring supports JSR-250 based annotations which include @Resource, @PostConstruct and @PreDestroy annotations.

So far you have seen how we configure Spring beans using XML configuration file. If you are comfortable with XML configuration, then it is really not required to learn how to proceed with Java-based configuration as you are going to achieve the same result using either of the configurations available.

Java-based configuration option enables you to write most of your Spring configuration without XML but with the help of few Java-based annotations explained in this chapter.

@Configuration & @Bean Annotations

Annotating a class with the @Configuration indicates that the class can be used by the Spring IoC container as a source of bean definitions. The @Bean annotation tells Spring that a method annotated with @Bean will return an object that should be registered as a bean in the Spring application context. The simplest possible @Configuration class would be as follows −

package com.tutorialspoint;
import org.springframework.context.annotation.*;

@Configuration
public class HelloWorldConfig {
   @Bean 
   public HelloWorld helloWorld(){
      return new HelloWorld();
   }
}

The above code will be equivalent to the following XML configuration −

<beans>
   <bean id = "helloWorld" class = "com.tutorialspoint.HelloWorld" />
</beans>

Here, the method name is annotated with @Bean works as bean ID and it creates and returns the actual bean. Your configuration class can have a declaration for more than one @Bean. Once your configuration classes are defined, you can load and provide them to Spring container using AnnotationConfigApplicationContext as follows −

public static void main(String[] args) {
   ApplicationContext ctx = new AnnotationConfigApplicationContext(HelloWorldConfig.class);
   
   HelloWorld helloWorld = ctx.getBean(HelloWorld.class);
   helloWorld.setMessage("Hello World!");
   helloWorld.getMessage();
}

You can load various configuration classes as follows −

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();
}

Example

Let us have a working Eclipse IDE in place and take the following steps to create a Spring application −

Steps Description
1 Create a project with a name SpringExample and create a package com.tutorialspoint under the src folder in the created project.
2 Add required Spring libraries using Add External JARs option as explained in the Spring Hello World Example chapter.
3 Because you are using Java-based annotations, so you also need to add CGLIB.jar from your Java installation directory and ASM.jar library which can be downloaded from asm.ow2.org.
4 Create Java classes HelloWorldConfig, HelloWorld and MainApp under the com.tutorialspoint package.
5 The final step is to create the content of all the Java files and Bean Configuration file and run the application as explained below.

Here is the content of HelloWorldConfig.java file

package com.tutorialspoint;
import org.springframework.context.annotation.*;

@Configuration
public class HelloWorldConfig {
   @Bean 
   public HelloWorld helloWorld(){
      return new HelloWorld();
   }
}

Here is the content of HelloWorld.java file

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);
   }
}

Following is the content of the MainApp.java file

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();
   }
}

Once you are done creating all the source files and adding the required additional libraries, let us run the application. You should note that there is no configuration file required. If everything is fine with your application, it will print the following message −

Your Message : Hello World!

Injecting Bean Dependencies

When @Beans have dependencies on one another, expressing that the dependency is as simple as having one bean method calling another as follows −

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();
   }
}

Here, the foo bean receives a reference to bar via the constructor injection. Now let us look at another working example.

Example

Let us have a working Eclipse IDE in place and take the following steps to create a Spring application −

Steps Description
1 Create a project with a name SpringExample and create a package com.tutorialspoint under the src folder in the created project.
2 Add required Spring libraries using Add External JARs option as explained in the Spring Hello World Example chapter.
3 Because you are using Java-based annotations, so you also need to add CGLIB.jar from your Java installation directory and ASM.jar library which can be downloaded from asm.ow2.org.
4 Create Java classes TextEditorConfig, TextEditor, SpellChecker and MainApp under the com.tutorialspoint package.
5 The final step is to create the content of all the Java files and Bean Configuration file and run the application as explained below.

Here is the content of TextEditorConfig.java file

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( );
   }
}

Here is the content of TextEditor.java file

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();
   }
}

Following is the content of another dependent class file SpellChecker.java

package com.tutorialspoint;

public class SpellChecker {
   public SpellChecker(){
      System.out.println("Inside SpellChecker constructor." );
   }
   public void checkSpelling(){
      System.out.println("Inside checkSpelling." );
   }
}

Following is the content of the MainApp.java file

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();
   }
}

Once you are done creating all the source files and adding the required additional libraries, let us run the application. You should note that there is no configuration file required. If everything is fine with your application, it will print the following message −

Inside SpellChecker constructor.
Inside TextEditor constructor.
Inside checkSpelling.

The @Import Annotation

The @Import annotation allows for loading @Bean definitions from another configuration class. Consider a ConfigA class as follows −

@Configuration
public class ConfigA {
   @Bean
   public A a() {
      return new A(); 
   }
}

You can import above Bean declaration in another Bean Declaration as follows −

@Configuration
@Import(ConfigA.class)
public class ConfigB {
   @Bean
   public B b() {
      return new B(); 
   }
}

Now, rather than needing to specify both ConfigA.class and ConfigB.class when instantiating the context, only ConfigB needs to be supplied as follows −

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-method 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, который управляет полным жизненным циклом бинов. ApplicationContext публикует определенные типы событий при загрузке bean-компонентов. Например, ContextStartedEvent публикуется при запуске контекста, а ContextStoppedEvent публикуется при остановке контекста.

Обработка в случае ApplicationContext обеспечивается через ApplicationEvent класса и ApplicationListener интерфейса. Следовательно, если bean-компонент реализует ApplicationListener , то каждый раз, когда ApplicationEvent публикуется в ApplicationContext, этот bean-компонент уведомляется.

Spring предоставляет следующие стандартные события -

Sr.No. Встроенные события Spring и описание
1

ContextRefreshedEvent

Это событие публикуется, когда ApplicationContext инициализируется или обновляется. Это также можно поднять с помощью метода refresh () в интерфейсе ConfigurableApplicationContext .

2

ContextStartedEvent

Это событие публикуется, когда ApplicationContext запускается с помощью метода start () в интерфейсе ConfigurableApplicationContext . Вы можете опросить свою базу данных или перезапустить любое остановленное приложение после получения этого события.

3

ContextStoppedEvent

Это событие публикуется, когда ApplicationContext останавливается с помощью метода stop () в интерфейсе ConfigurableApplicationContext . После получения этого события вы можете выполнять необходимую работу по хозяйству.

4

ContextClosedEvent

Это событие публикуется, когда ApplicationContext закрывается с помощью метода close () в интерфейсе ConfigurableApplicationContext . Закрытый контекст подходит к концу; его нельзя обновить или перезапустить.

5

RequestHandledEvent

Это веб-событие, сообщающее всем bean-компонентам, что HTTP-запрос был обработан.

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

Прослушивание контекстных событий

Чтобы прослушивать событие контекста, bean-компонент должен реализовывать интерфейс ApplicationListener, который имеет только один метод.onApplicationEvent(). Итак, давайте напишем пример, чтобы увидеть, как распространяются события, и как вы можете поместить свой код для выполнения требуемой задачи на основе определенных событий.

Разрешите нам иметь рабочую среду разработки Eclipse и предпринять следующие шаги для создания приложения Spring:

Шаг Описание
1 Создайте проект с именем SpringExample и создайте пакет com.tutorialspoint подsrc папку в созданном проекте.
2 Добавьте необходимые библиотеки Spring с помощью опции « Добавить внешние JAR», как описано в главе « Пример Spring Hello World» .
3 Создайте классы Java HelloWorld , CStartEventHandler , CStopEventHandler и MainApp в пакете com.tutorialspoint .
4 Создайте файл конфигурации Beans Beans.xml подsrc папка.
5 Последний шаг - создать содержимое всех файлов Java и файла конфигурации компонента и запустить приложение, как описано ниже.

Вот содержание 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

При желании вы можете опубликовать свои собственные события, а позже вы можете записать их, чтобы предпринять какие-либо действия против этих настраиваемых событий. Если вы заинтересованы в написании собственных пользовательских событий, вы можете проверить Custom Events в Spring.

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

Шаги Описание
1 Создайте проект с именем SpringExample и создайте пакет com.tutorialspoint подsrcпапку в созданном проекте. Все классы будут созданы в этом пакете.
2 Добавьте необходимые библиотеки Spring с помощью опции « Добавить внешние JAR», как описано в главе « Пример Spring Hello World» .
3 Создайте класс события CustomEvent , расширивApplicationEvent. Этот класс должен определять конструктор по умолчанию, который должен наследовать конструктор от класса ApplicationEvent.
4 Как только ваш класс событий определен, вы можете опубликовать его из любого класса, скажем, EventClassPublisher, который реализует ApplicationEventPublisherAware . Вам также нужно будет объявить этот класс в файле конфигурации XML как bean-компонент, чтобы контейнер мог идентифицировать bean-компонент как публикатора событий, поскольку он реализует интерфейс ApplicationEventPublisherAware.
5 Опубликованное событие может обрабатываться в классе, скажем, EventClassHandler, который реализует интерфейс ApplicationListener и реализует метод onApplicationEvent для настраиваемого события.
6 Создайте файл конфигурации beans Beans.xml подsrcпапка и класс MainApp, который будет работать как приложение Spring.
7 Последний шаг - создать содержимое всех файлов Java и файла конфигурации компонента и запустить приложение, как описано ниже.

Вот содержание 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 является Aspect oriented programming (AOP)фреймворк. Аспектно-ориентированное программирование влечет за собой разбиение логики программы на отдельные части, так называемые задачи. Функции, охватывающие несколько точек приложения, называютсяcross-cutting concernsи эти сквозные проблемы концептуально отделены от бизнес-логики приложения. Существуют различные общие хорошие примеры таких аспектов, как ведение журнала, аудит, декларативные транзакции, безопасность, кеширование и т. Д.

Ключевой единицей модульности в ООП является класс, тогда как в АОП единицей модульности является аспект. Внедрение зависимостей помогает отделить объекты приложения друг от друга, а АОП помогает отделить сквозные проблемы от объектов, на которые они влияют. АОП похож на триггеры в таких языках программирования, как Perl, .NET, Java и другие.

Модуль Spring AOP предоставляет перехватчики для перехвата приложения. Например, при выполнении метода вы можете добавить дополнительные функции до или после выполнения метода.

Терминология АОП

Прежде чем мы начнем работать с АОП, давайте познакомимся с концепциями и терминологией АОП. Эти термины не относятся к Spring, скорее, они связаны с АОП.

Старший Нет Условия и описание
1

Aspect

Это модуль, который имеет набор API, обеспечивающий сквозные требования. Например, модуль ведения журнала будет называться аспектом АОП для ведения журнала. Приложение может иметь любое количество аспектов в зависимости от требований.

2

Join point

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

3

Advice

Это фактическое действие, которое нужно предпринять до или после выполнения метода. Это реальный фрагмент кода, который вызывается во время выполнения программы фреймворком Spring AOP.

4

Pointcut

Это набор из одной или нескольких точек соединения, в которых должен выполняться совет. Вы можете указать pointcut с помощью выражений или шаблонов, как мы увидим в наших примерах АОП.

5

Introduction

Введение позволяет вам добавлять новые методы или атрибуты к существующим классам.

6

Target object

Объект, о котором сообщают один или несколько аспектов. Этот объект всегда будет прокси-объектом, также называемым рекомендованным объектом.

7

Weaving

Плетение - это процесс связывания аспектов с другими типами приложений или объектами для создания рекомендованного объекта. Это можно сделать во время компиляции, загрузки или во время выполнения.

Типы советов

Аспекты Spring могут работать с пятью видами советов, перечисленных ниже:

Старший Нет Совет и описание
1

before

Выполнить совет перед выполнением метода.

2

after

Выполнять совет после выполнения метода, независимо от его результата.

3

after-returning

Выполнять совет после выполнения метода, только если метод завершился успешно.

4

after-throwing

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

5

around

Выполните advice до и после вызова рекомендованного метода.

Реализация пользовательских аспектов

Весна поддерживает @AspectJ annotation style подход и schema-basedподход к реализации нестандартных аспектов. Эти два подхода подробно описаны в следующих разделах.

Старший Нет Подход и описание
1 На основе XML-схемы

Аспекты реализуются с использованием обычных классов вместе с конфигурацией на основе XML.

2 На основе @AspectJ

@AspectJ относится к стилю объявления аспектов как обычных классов Java, аннотированных аннотациями Java 5.

При работе с базой данных с использованием простого старого JDBC становится громоздко писать ненужный код для обработки исключений, открытия и закрытия соединений с базой данных и т.д. Однако Spring JDBC Framework заботится обо всех низкоуровневых деталях, начиная с открытия соединения, подготовьте и выполнить инструкцию SQL, обработать исключения, обработать транзакции и, наконец, закрыть соединение.

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

Spring JDBC предоставляет несколько подходов и, соответственно, разные классы для взаимодействия с базой данных. Я собираюсь использовать классический и самый популярный подход, который используетJdbcTemplateкласс каркаса. Это центральный класс инфраструктуры, который управляет всем взаимодействием с базой данных и обработкой исключений.

Класс JdbcTemplate

Класс JDBC Template выполняет запросы SQL, обновляет операторы, сохраняет вызовы процедур, выполняет итерацию по ResultSets и извлекает возвращаемые значения параметров. Он также перехватывает исключения JDBC и преобразует их в общую, более информативную иерархию исключений, определенную в пакете org.springframework.dao.

Экземпляры JdbcTemplate класса поточно после настройки. Таким образом, вы можете настроить один экземпляр JdbcTemplate, а затем безопасно внедрить эту общую ссылку в несколько DAO.

Распространенной практикой при использовании класса JDBC Template является настройка DataSource в вашем конфигурационном файле Spring, а затем внедрение зависимости этого общего bean-компонента DataSource в ваши классы DAO, и JdbcTemplate создается в установщике для DataSource.

Настройка источника данных

Создадим таблицу базы данных 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)
);

Теперь нам нужно предоставить DataSource в шаблон JDBC, чтобы он мог настроить себя для получения доступа к базе данных. Вы можете настроить DataSource в 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 Template.

Querying for an integer

String SQL = "select count(*) from Student";
int rowCount = jdbcTemplateObject.queryForInt( SQL );

Querying for a long

String SQL = "select count(*) from Student";
long rowCount = jdbcTemplateObject.queryForLong( SQL );

A simple query using a bind variable

String SQL = "select age from Student where id = ?";
int age = jdbcTemplateObject.queryForInt(SQL, new Object[]{10});

Querying for a String

String SQL = "select name from Student where id = ?";
String name = jdbcTemplateObject.queryForObject(SQL, new Object[]{10}, String.class);

Querying and returning an object

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;
   }
}

Querying and returning multiple objects

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;
   }
}

Inserting a row into the table

String SQL = "insert into Student (name, age) values (?, ?)";
jdbcTemplateObject.update( SQL, new Object[]{"Zara", 11} );

Updating a row into the table

String SQL = "update Student set name = ? where id = ?";
jdbcTemplateObject.update( SQL, new Object[]{"Zara", 10} );

Deleting a row from the table

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 весной

Узнайте, как вызвать хранимую процедуру SQL при использовании JDBC в Spring.

Транзакция базы данных - это последовательность действий, которые рассматриваются как единая единица работы. Эти действия должны быть либо завершены полностью, либо не иметь никакого эффекта. Управление транзакциями является важной частью корпоративного приложения, ориентированного на СУБД, для обеспечения целостности и согласованности данных. Концепцию транзакций можно описать с помощью следующих четырех ключевых свойств, описанных какACID -

  • Atomicity - Транзакция должна рассматриваться как единая операция, что означает, что либо вся последовательность операций успешна, либо неуспешна.

  • Consistency - Это представляет собой согласованность ссылочной целостности базы данных, уникальных первичных ключей в таблицах и т. Д.

  • Isolation- Одновременно может выполняться несколько операций обработки с одним и тем же набором данных. Каждая транзакция должна быть изолирована от других, чтобы предотвратить повреждение данных.

  • Durability - После завершения транзакции результаты этой транзакции должны быть постоянными и не могут быть удалены из базы данных из-за сбоя системы.

Настоящая СУБД гарантирует все четыре свойства для каждой транзакции. Упрощенный вид транзакции, отправляемой в базу данных с использованием SQL, выглядит следующим образом:

  • Начните транзакцию с помощью команды begin transaction .

  • Выполняйте различные операции удаления, обновления или вставки с помощью SQL-запросов.

  • Если все операции выполнены успешно, выполните фиксацию, в противном случае откатите все операции.

Инфраструктура Spring предоставляет абстрактный слой поверх различных базовых API управления транзакциями. Поддержка транзакций Spring направлена ​​на предоставление альтернативы транзакциям EJB путем добавления транзакционных возможностей в POJO. Spring поддерживает как программное, так и декларативное управление транзакциями. Для EJB-компонентов требуется сервер приложений, но управление транзакциями Spring может быть реализовано без необходимости в сервере приложений.

Локальные и глобальные транзакции

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

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

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

Программные и декларативные продажи

Spring поддерживает два типа управления транзакциями -

  • Программное управление транзакциями - это означает, что вы должны управлять транзакцией с помощью программирования. Это дает вам чрезвычайную гибкость, но его сложно поддерживать.

  • Декларативное управление транзакциями - это означает, что вы отделяете управление транзакциями от бизнес-кода. Для управления транзакциями вы используете только аннотации или конфигурацию на основе XML.

Декларативное управление транзакциями предпочтительнее программного управления транзакциями, хотя оно менее гибкое, чем программное управление транзакциями, которое позволяет вам контролировать транзакции через ваш код. Но декларативное управление транзакциями можно разделить на модули с помощью подхода АОП. Spring поддерживает декларативное управление транзакциями через платформу Spring AOP.

Абстракции Spring транзакций

Ключ к абстракции транзакции 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;
}

Старший Нет Метод и описание
1

TransactionStatus getTransaction(TransactionDefinition definition)

Этот метод возвращает текущую активную транзакцию или создает новую в соответствии с указанным поведением распространения.

2

void commit(TransactionStatus status)

Этот метод фиксирует данную транзакцию с учетом ее статуса.

3

void rollback(TransactionStatus status)

Этот метод выполняет откат данной транзакции.

TransactionDefinition является основным интерфейсом поддержки транзакций в Spring и определяются следующим образом: -

public interface TransactionDefinition {
   int getPropagationBehavior();
   int getIsolationLevel();
   String getName();
   int getTimeout();
   boolean isReadOnly();
}

Старший Нет Метод и описание
1

int getPropagationBehavior()

Этот метод возвращает поведение распространения. Spring предлагает все варианты распространения транзакций, знакомые по EJB CMT.

2

int getIsolationLevel()

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

3

String getName()

Этот метод возвращает имя этой транзакции.

4

int getTimeout()

Этот метод возвращает время в секундах, в течение которого транзакция должна завершиться.

5

boolean isReadOnly()

Этот метод возвращает, доступна ли транзакция только для чтения.

Ниже приведены возможные значения уровня изоляции -

Старший Нет Изоляция и описание
1

TransactionDefinition.ISOLATION_DEFAULT

Это уровень изоляции по умолчанию.

2

TransactionDefinition.ISOLATION_READ_COMMITTED

Указывает, что грязное чтение предотвращено; могут происходить неповторяющиеся чтения и фантомные чтения.

3

TransactionDefinition.ISOLATION_READ_UNCOMMITTED

Указывает, что могут происходить грязные, неповторяющиеся чтения и фантомные чтения.

4

TransactionDefinition.ISOLATION_REPEATABLE_READ

Указывает, что грязное чтение и неповторяющееся чтение предотвращены; могут происходить фантомные чтения.

5

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

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

Интерфейс TransactionStatus обеспечивает простой способ для кода транзакции контролировать выполнение транзакции и запрашивать состояние транзакции.

public interface TransactionStatus extends SavepointManager {
   boolean isNewTransaction();
   boolean hasSavepoint();
   void setRollbackOnly();
   boolean isRollbackOnly();
   boolean isCompleted();
}

Sr.No. Метод и описание
1

boolean hasSavepoint()

Этот метод возвращает, содержит ли эта транзакция внутреннюю точку сохранения, т. Е. Была ли создана как вложенная транзакция на основе точки сохранения.

2

boolean isCompleted()

Этот метод возвращает, завершена ли эта транзакция, т. Е. Была ли она уже зафиксирована или отменена.

3

boolean isNewTransaction()

Этот метод возвращает истину, если текущая транзакция новая.

4

boolean isRollbackOnly()

Этот метод возвращает, была ли транзакция помечена как откатная.

5

void setRollbackOnly()

Этот метод устанавливает транзакцию только для отката.

Инфраструктура Spring Web MVC предоставляет архитектуру модель-представление-контроллер (MVC) и готовые компоненты, которые можно использовать для разработки гибких и слабосвязанных веб-приложений. Шаблон MVC приводит к разделению различных аспектов приложения (логика ввода, бизнес-логика и логика пользовательского интерфейса), обеспечивая при этом слабую связь между этими элементами.

  • В Model инкапсулирует данные приложения и обычно состоит из POJO.

  • В View отвечает за визуализацию данных модели и, как правило, генерирует вывод HTML, который может интерпретировать браузер клиента.

  • В Controller отвечает за обработку запросов пользователей и построение соответствующей модели и передает ее представлению для рендеринга.

ДиспетчерСервлет

Инфраструктура Spring Web Model-View-Controller (MVC) разработана на основе DispatcherServlet, который обрабатывает все HTTP-запросы и ответы. Рабочий процесс обработки запросов Spring Web MVC DispatcherServlet проиллюстрирован на следующей диаграмме:

Ниже приводится последовательность событий , соответствующих входящего запроса HTTP к 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.xml файл будет использоваться для создания бобы , определенной, перекрывая определения любых бобов , определенных с тем же именем в глобальном масштабе.

  • <Контекст: компонент сканирование ...> тег будет использовать , чтобы активизировать аннотации возможность сканирования Spring MVC , которая позволяет использовать аннотации как @Controller и @RequestMapping т.д.

  • InternalResourceViewResolver будет иметь определенные правила для разрешения имен просмотра. Согласно определенному выше правилу, логическое представление с именемhelloделегируется реализации представления, расположенной по адресу /WEB-INF/jsp/hello.jsp .

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

Определение контроллера

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-адрес, которому сопоставлен метод обработчика, и methodАтрибут определяет метод службы для обработки HTTP-запроса GET. Следует отметить следующие важные моменты относительно контроллера, определенного выше:

  • Вы определите необходимую бизнес-логику внутри метода обслуживания. Вы можете вызвать другой метод внутри этого метода в соответствии с требованиями.

  • На основе определенной бизнес-логики вы создадите модель в этом методе. Вы можете использовать установщик различных атрибутов модели, и эти атрибуты будут доступны представлению для представления окончательного результата. В этом примере создается модель с атрибутом «сообщение».

  • Определенный метод службы может возвращать строку, содержащую имя viewбудет использоваться для рендеринга модели. В этом примере в качестве имени логического представления возвращается «hello».

Создание представлений JSP

Spring MVC поддерживает множество типов представлений для различных технологий представления. К ним относятся - JSP, HTML, PDF, листы Excel, XML, шаблоны Velocity, XSLT, JSON, Atom и RSS-каналы, JasperReports и т. Д. Но чаще всего мы используем шаблоны JSP, написанные с помощью JSTL.

Напишем простой hello посмотреть в /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

Узнайте, как использовать функцию перенаправления страниц в Spring MVC Framework.

4 Пример статических страниц Spring

Узнайте, как получить доступ к статическим страницам вместе с динамическими страницами в Spring MVC Framework.

5 Пример обработки исключений Spring

Узнайте, как обрабатывать исключения в Spring MVC Framework.

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

Мы предполагаем, что у вас уже есть log4Jустановлен на вашем компьютере. Если у вас его нет, вы можете скачать его сhttps://logging.apache.org/и просто распакуйте заархивированный файл в любую папку. Мы будем использовать толькоlog4j-x.y.z.jar в нашем проекте.

Затем позвольте нам иметь рабочую среду IDE Eclipse и предпринять следующие шаги для разработки веб-приложения на основе динамических форм с использованием Spring Web Framework:

Шаги Описание
1 Создайте проект с именем SpringExample и создайте пакет com.tutorialspoint подsrc папку в созданном проекте.
2 Добавьте необходимые библиотеки Spring с помощью опции « Добавить внешние JAR», как описано в главе « Пример Spring 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 и файла конфигурации компонента и запустить приложение, как описано ниже.

Вот содержание 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");
   }
}

Вы можете создать debug и errormessage аналогично тому, как мы создавали информационные сообщения. Теперь давайте посмотрим на содержание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

В качестве альтернативы вы можете использовать Jakarta Commons Logging (JCL)API для создания журнала в вашем приложении 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.