иФреймворк Spring построен на принципе “Inversion of Control (IoC)” Dependency injection — имплементирует принцип “IoC” в приложении. 

Цель этой статьи состоит в том чтобы объяснить базовую концепцию контейнера Spring IoC и Spring Bean на примере.

Spring IoC Container

Inversion of Control это механизм, который обеспечивает достижение слабой связности в зависимостях между объектами. Слабая связанность объектов достигается путем использования динамического связывания(инъекции) одного объекта с другим во время выполнения программы. Spring IoC контейнер является инструментом который вставляет(inject) зависимости в объект и тем самым делает его готовым к использованию.

Классы Spring Framework IoC контейнера являются частью org.springframework.beans и org.springframework.context пакетов.

BeanFactory — основной интерфейс контейнера Spring IoC. ApplicationContext — расширяет интерфейс BeanFactory возможностями Spring AOP , интернационализации и другими инструментами. Одни из самых полезных интерфейсов, которые расширяют ApplicationContext это: ConfigurableApplicationContext и WebApplicationContext. В фреймворке Spring есть несколько полезных имплементаций интерфейса ApplicationContext, используя которые можно получить контекст(context) и потом бин(Spring Bean):

  • AnnotationConfigApplicationContext: используют для инициализации контекста и получения объекта бина в случае если Spring используется в автономном приложении и используются аннотации для его конфигурации.
  • ClassPathXmlApplicationContext:  используют для загрузки XML файла и получения объекта контейнера в случае если Spring используется в автономном приложении и используется XML файл для его конфигурации.
  • FileSystemXmlApplicationContext: то же самое что и ClassPathXmlApplicationContext за исключением того что может подгрузить XML файл с любого места файловой системы.
  • AnnotationConfigWebApplicationContext и XmlWebApplicationContext для  Web приложений.

В автономном приложении вы должны инициализировать Spring IoC контейнер где-то в приложении и использовать его для получения бинов.
Однако, если вы работаете с Spring MVC приложением и ваше приложение сконфигурировано с использованием фреймворка Spring, то Spring IoC контейнер инициализируеться когда приложение стартует, и зависимости автоматически вставляются(injected) когда бины используются.

Spring Bean

Любой объект в фреймворке Spring, который инициализируется через Spring IoC контейнер называется Spring Bean. Любой Java POJO класс может быть Spring бином если его сконфигурировать.

Spring Bean Scopes

Определено пять ограничений(scopes) для бинов(Spring Beans).

  • singleton — только один экземпляр бина будет создан для каждого контейнера.   Это ограничение установлено по умолчанию для бинов спринга.
  • prototype — при каждом запросе на получение бина будет возвращен новый экземпляр бина.
  • request — тоже самое что и prototype только для Web приложений. Новый экземпляр бина будет создан при каждом HTTP запросе.
  • session — новый экземпляр бина будет создан для каждой HTTP сессий.
  • global-session — используется для создания бина в глобальной сессии для портлет(Portlet) приложений.

Фреймворк Spring является расширяемым и мы можем создать собственные ограничения(scopes) для бина, но в большинстве случаев достаточно использовать стандартные ограничения(scope).

Spring Bean Configuration

Фреймворк Spring предоставляет три способа для конфигурации бинов в приложении.

  • Аннотации(Annotation Based Configuration) — используя @Service или @Component аннотации. Задать ограничение(scope) можно используя аннотацию @Scope.
  • XML файлы(XML Based Configuration) — создание XML файла с конфигурацией для бинов.
  • Java конфигурация (Java Based Configuration) — начиная с версии фреймворка Spring 3.0 можно сконфигурировать бины используя Java код. Некоторые из важных аннотаций которые используются при этом подходе: @Configuration, @ComponentScan и @Bean.

Spring IoC and Bean Example Project

Создан maven проект spring-beans, включена поддержка фреймворка Spring + SpringMVC(в результате чего создана папка web). Cтруктура проекта выглядит следующим образом:

project

Теперь рассмотрим в деталях каждый его элемент.

Файл pom.xml выглядит следующим образом:

pom.xml

XML Based Bean Configuration

MyBean это обычный Java POJO класс

MyBean.java

Spring Configuration XML File

Ниже приведена конфигурация фреймворка Spring.

servlet-context.xml

servlet-context.xml

Отмечу что MyBean сконфигурирован с помощью элемента bean используя ограничение(scope) singleton.

Annotation Based Bean Configuration

MyAnnotatedBean.java

MyAnnotatedBean сконфигурирован с помощью аннотации @Service используя ограничение(scope) request.

Controller Class

Класс HomeController будет обрабатывать HTTP запрос от страници home. Инъекция(inject) бинов фреймворка Spring в этот контроллер класс выполнена с использованием контейнера WebApplicationContext.

HomeController.java

Deployment Descriptor

Ниже приведена конфигурация приложения для подгрузки файла конфигурации фреймворка Spring и инициализации контекста.

web.xml

web.xml

Run the Web Application

После запуска приложения в консоль будет выведен следующий log.

MyBean hashcode=118267258
MyAnnotatedBean hashcode=1703899856
MyBean hashcode=118267258
MyAnnotatedBean hashcode=1115599742
MyBean hashcode=118267258
MyAnnotatedBean hashcode=516457106

Отмечу что MyBean был сконфигурирован с ограничением(scope) singleton в итоге контейнер возвращает один и тот же экземпляр и соответсвенно hashcode всегда одинаковый. MyAnnotatedBean был сконфигурирован с ограничением(scope)  request в итоге контейнер возвращает каждый раз новый экземпляр класса MyAnnotatedBean.

Java Based Bean Configuration

В автономном приложении можно использовать аннотации или XML для конфигурирования фреймворка Spring. Но нужно инициализировать контекст где-то в приложении перед тем как его использовать.

MyService.java

MyService — обычный Java класс с методом.

MyConfiguration.java

Конфигурационный класс который будет использоваться для инициализации контейнера фреймворка Spring.

MyMainClass.java

Тестовая программа где осуществляется инициализация AnnotationConfigApplicationContext контекста и использование метода getBean() для получения объекта класса MyService.Отмечу что в данной программе вызывается метод getBean() два раза и выводится hashcode. Поскольку не определено ограничения(scope) для класса MyService, он должен быть с ограничением(scope) singleton и hashcode должен быть одинаков в обоих случаях.

После запуска программы которая приведена выше в консоль выводится следующий результат.

Wed Feb 10 17:17:36 EET 2016::Hi
service hashcode=225290371
newService hashcode=225290371

Если нужно сконфигурировать приложение используя XML — необходимо создать конфигурационный XML файл и инициализировать контекст используя следующий код:

[/fusion_builder_column][/fusion_builder_row][/fusion_builder_container]

Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.