Руководство по Spring. Введение в Bean-ы.
Мы продолжаем наш цикл туториалов по Spring Framework, и сегодня речь пойдёт о сущности под названием Bean (бин).
Бины – это объекты, которые являются основой приложения и управляются Spring IoC контейнером. Эти объекты создаются с помощью конфигурационных метаданных, которые указываются в контейнере (например, XML- … ). Я уже говорил о них в предыдущих главах.
Определение бина содержит метаданные конфигурации, которые необходимы управляющему контейнеру для получения следующей информации:
В Spring Framework существуют такие свойства, определяющие бины:
class
Этот атрибут является обязательным и указывает конкретный класс Java-приложения, который будет использоваться для создания бина.
name
Уникальный идентификатор бина. В случае конфигурации с помощью xml-файла, вы можете использовать свойство “id” и/или “name” для идентификации бина.
scope
Это свойство определяет область видимости создаваемых объектов. (Прим. Отсутствие в русском языке достойного перевода этого свойства бинов могут вызвать затруднения, но более подробно оно будет рассмотрено далее).
constructor-arg
Определяет конструктор, использующийся для внедрения зависимости. Более подробно – далее.
properties
Определяет свойства внедрения зависимости. Более подробно рассмотрим далее.
initialization method
Здесь определяется метод инициализации бина
destruction method
Метод уничтожения бина, который будет использоваться при уничтожении контейнера, содержащего бин.
autowiring mode
Определяет режим автоматического связывания при внедрении зависимости. Более подробно рассмотрим далее.
lazy-initialization mode
Режим ленивой инициализации даёт контейнеру IoC команду создавать экземпляр бина при первом запросе, а не при запуске приложения.
Контейнер IoC не зависит от формата, в котором передаются метаданные. Существует 3 основных метода передачи метаданных контейнеру Spring IoC:
Ранее мы уже рассматривали как передаются метаданные на основе XML-файла. Теперь давайте рассмотрим пример XML-файла с различными свойствами
Конфигурирование бинов с помощью аннотаций мы рассмотрим позже в отдельной главе.
Урок 2: Введение в Spring IoC контейнер
Этот урок освещает работу с Spring Framework IoC контейнером и основан на оригинальной документации §5. The IoC container.
Что вы создадите
Вы создадите некоторое количество классов, в которых будет рассмотрена функциональность Spring Framework IoC контейнера.
Что вам потребуется
Настройка проекта
Введение
Inversion of Control (IoC), также известное как Dependency Injection (DI), является процессом, согласно которому объекты определяют свои зависимости, т.е. объекты, с которыми они работают, через аргументы конструктора/фабричного метода или свойства, которые были установлены или возвращены фабричным методом. Затем контейнер inject(далее «внедряет») эти зависимости при создании бина. Этот процесс принципиально противоположен, поэтому и назван Inversion of Control, т.к. бин сам контролирует реализацию и расположение своих зависимостей, используя прямое создание классов или такой механизм, как шаблон Service Locator.
Описание работы IoC контейнера
ApplicationContext представляет собой Spring IoC контейнер и необходим для инициализации, настройки и сборки бинов для построения приложения.
В метаданных конфигурации разработчик описывает как инициализировать, настроить IoC контейнер и собрать объекты в вашем приложении. В данном и других уроках этого цикла везде, где возможно, будет использоваться подход на основе аннотаций и Java-конфигурации. Если вы сторонник XML-конфигурации, либо хотите посмотреть как делать тоже самое через XML, обратитесь к оригинальной документации по Spring Framework или соответствующего модуля/проекта.
Настройка IoC контейнера
Как вариант, можно инициализировать контекст(ы) таким образом:
Использование @Bean аннотации
Теперь, для того, чтобы объект с типом GreetingService был доступен для использования, необходимо описать его в конфигурации следующим образом:
А для того, чтобы использовать его, достаточно выполнить следующее:
Метод getBean() может принимать в качестве аргумента как класс(как показано выше), так и названия бина(подробнее будет рассмотрено ниже), либо другие варианты, с которыми вы можете ознакомится в документации. Однако такой подход не рекомендуется использовать в production-конфигурациях, т.к. для подобных целей существует механизм Dependency Injection (DI), собственно говоря, для чего и предназначен Spring IoC контейнер. Использование DI будет рассмотрено ниже в отдельной главе.
Иногда полезно предоставить более подробное описание бина, например, в целях мониторинга. Для этого существует аннотация @Description :
Жизненный цикл бина
При совместном использовании методов, интерфейсов и аннотаций, описанных выше, учитывайте их порядок вызовов. Для методов инициализации порядок будет следующий:
Для методов разрушения порядок будет следующий:
Если вам необходимо реализовать свою собственную модель жизненного цикла бина, то в таком случае бин должен реализовывать один из интерфейсов, приведенных ниже:
После этого у вас появятся результаты работы методов при разрушении бина. Однако стоит заметить ещё раз, что это относится к обычным приложения, не относящимся к web-приложения(поскольку для них применяется отдельный тип контекста и подобный метод в них уже есть).
Области видимости(scopes) бинов
Когда вы создаете определение бинов, вы вы создаете рецепт для создания экземпляров класса, который определяет бин. Важно понять, что определение бинов является рецептом, потому что он означает, какого класса вы можете создать множество экземпляров по этому рецепту.
Использование @Configuration аннотации
Кода бин имеет зависимость от другого бина, то зависимость выражается просто как вызов метода:
В большинстве случаев, имеются такие случаи, когда бин в одной конфигурации имеет зависимость от бина в другой конфигурации. Поскольку конфигурация является источником определения бинов, то разрешить такую зависимость не является проблемой, достаточно объявить поле класса конфигурации с аннотацией @Autowired (более подробно оисано в отдельной главе):
При этом LessonsConfiguration остается без изменений:
Процесс разрешения зависимостей
IoC контейнер выполняет разрешение зависимостей бинов в следующем порядке:
Spring контейнер может разрешать зависимости между бинами через autowiring(далее, автоматическое связывание). Данный механизм основан на просмотре содержимого в ApplicationContext и имеет следующие преимущества:
Соответственно, у одной из реализации GreetingService должна быть установлена соответствующая аннотация @Qualifier :
Spring также поддерживает использование JSR-250 @Resource аннотации автоматического связывания для полей класса или параметров setter-методов:
Использование стандартных JSR-330 аннотаций
Spring Framework поддерживает JSR-330 аннотации. Эти аннотации работают таким же способом, как и Spring аннотации. Для того, чтобы работать с ними, необходимо добавить в pom.xml следующую зависимость:
Ниже приведена таблица сравнения JSR-330 и Spring аннотаций для DI:
Spring какие бины будут использоваться для настройки приложения
Spring. Первые шаги
Данный фреймворк имеет высокую модульность, каждый модуль способен запускаться и выполнять свои задачи как самостоятельное приложение, либо же может использоваться в группе с другими модулями (фреймворки в фреймворке). Функционал спринга постоянно обновляется и дополняется, наиболее популярные модули реализуют функционал MVC, работы с базой данных, секьюрности приложений, обмена сообщений, шаблонизаторов и многого другого.
И в обратную сторону: Контейнер + метаданные (настройки) позволяют запустить образуют ваше приложение с контейнером, который управляет бинами.
Первая задача. HelloWorld.
Всего 3 класса и одна зависимость.
Класс App содержит метод мейн, с которого запускается спринг при создании контекста. В контекст мы передаем класс AppConfig, который помечен аннотацией @Configuration, так спринг понимает, что это настроечный класс.
В классе AppConfig содержится метод, помеченный аннотацией как бин, этот метод будет выполнен при запуске и его результат станет объектом управляемым спрингом.
Класс HelloWorld является обычным джава-классом, мы его используем без каких-либо сложностей.
В методе мейн мы можем получить бин ХеллоВорлд по имени и использовать в любом месте программы.
Спринг позволяет использовать различные типы бинов, одни будут жить от старта до завершения программы, другие будут создаваться при каждом реквесте или открытии новой сессии, третьи при каждом вызове будут создаваться новые. За это отвечает аннотация @Scope.
Задача 2. Spring Beans
Теперь поработаем со связыванием бинов. Вызывать бины из контекста хорошо, но не так удобно, как связывать их автоматически.
Для работы аннотаций связывания, я добавил в мавен ядро спринга, так мы имеем совершенно рабочее спринг приложение, хоть и без дополнительных модулей.
В компоненте AnimalCage есть поле типа Animal, которое связано с помощью аннотации @Autowired. При выполнении программы DI-контейнер потянет сюда бин, подходящий по типу.
Задача 3. Виды связывания бинов.
Чтобы спринг видел все бины, в классе AppConfig была добавлена аннотация @ComponentScan.
В спринге связать бины можно различными способами, рассмотрим их на примере:
Собрать цепочку до 8го элемента, использовав все вышеперечисленные методы связывания. После выполнения вы должны получить полную фразу.
Вопросы для самопроверки:
Настройка приложения — Spring Configuration Metadata
Для создания настройки приложения с использованием ConfigurationProperties, можно начать с класса свойств. В нем собственно указаны свойства, компоненты системы которые хотим настраивать.
В классе prefix=«demo» будет использоваться в application.properties, как префикс к свойству.
Тут я объявил два spring бина
В классе AppProperties я указал ссылку на некоторый доступный сервис приложения, его я буду менять в application.properties, у меня будет две его реализации и я буду подключать одну из них в application.properties.
При попытке ввести неверный тип IDE сообщит
Даже если оставить как есть и попытаться стартовать приложение, то будет вполне внятная ошибка
Добавление дополнительных метаданных
В ней можно будет перечислить например допустимые значения для demo.vehicle
В поле «name» указано св-во «demo.vehicle», а в «values» список допустимых значений. Теперь если сделать rebuild проекта и перейти в файл application.properties, то при вводе demo.vehicle получу список допустимых значений
При вводе отличного от предложенного, но того же типа, редактор подсветит, но приложение в этом случае будет стартовать, так как это не строгое ограничение, а всего лишь подсказка.
Пример Providers для DemoService:
После чего в application.properties для параметра demo.service будет доступен выбор двух сервисов, можно посмотреть их описание (description из определения).
Теперь удобно выбирать нужный сервис, менять функционал приложения. Есть один момент для объектных настроек, Spring надо немного помочь конвертировать строку которая указана в настройке, в объект. Для этого делается небольшой класс наследник от Converter.
На диаграмме классов проекта видно как эти сервисы отделены от основного приложения и доступны через AppProperties.
К полям класса AppProperties можно добавить проверки доступные в рамках JSR 303. Про это я писал здесь. Получится проверяемый, удобный файл конфигурации приложения.
Узнайте, как привязать бины Spring с использованием XML и классов Java
Для подключения компонентов Spring используются два подхода: конфигурация XML и класс Java. Привязка может быть выполнена вручную путем настройки XML- файлов или с помощью классов Java. Также можно позволить Spring выполнить привязку на основе нескольких спецификаций.
Основная цель этой статьи – показать, как компоненты Spring могут быть привязаны с помощью двух упомянутых выше подходов.
Для чего используется фреймворк Spring?
Spring Framework — это одна из популярных сред разработки приложений, которая имеет следующие преимущества:
Spring использует другие технологии: фреймворки логов, ORM, таймеры Quartz, JEE и JDK и другие.
Что такое привязка бинов?
Когда запускается программное приложение, совместно работают сразу несколько объектов (бинов). Также они могут использоваться независимо от других объектов.
Чтобы заставить бины работать вместе, их связывают через введение зависимостей в Spring (привязки). Когда запускается приложение на основе Spring, контекст приложения загружает определения компонентов или объектов из файла конфигурации и связывает их вместе.
Существует два подхода к привязке bean-компонентов в среде Spring:
Что такое автоматическая привязка?
Существует два способа привязки bean-компонентов в среде Spring:
Последний способ известен как автоматическая привязка. При этом контейнеру Spring нужно указать, как он должен их связывать:
Что такое привязка через Java и XML?
Подключение bean-компонентов Spring может выполняться через классы Java и с помощью конфигурации XML. В этом разделе мы рассмотрим оба варианта:
.
Классы Java: Необходимо создать класс Spring Configuration и аннотировать класс @Configuration. Класс @Configuration сообщает Spring, что bean-компоненты, которые должны быть подключены и настроены в этом классе.
Настройка среды
Настройка среды для разработки приложений Spring, включает в себя всего три основных шага.
Пример приложения
Мы разработаем два приложения. В первом бины будут подключаться с использованием аннотаций, а во втором приложении – с помощью XML-файла конфигурации.
Подключение через аннотации — у нас будет три класса Java, как показано ниже.
Листинг 1: Класс бина
В следующем классе для информирования контейнера Spring о том, что будет загружен beanWire, используются две аннотации. Аннотация @Configuration сообщает контейнеру Spring, что этот класс является источником определений бина.
Аннотация @Bean информирует среду Spring, что метод вернет объект, который должен быть зарегистрирован как компонент в контексте приложения.
Листинг 2: Класс конфигурации Bean с аннотациями
Ниже приведен последний класс для запуска приложения.
Листинг 3: Основной класс для запуска приложения
Когда эта Java-программа будет выполнена, она выдаст следующий результат.
Теперь рассмотрим, как привязывать бины через XML-файл.
Привязка через XML-файл: У нас будет два Java-файла и один XML-файл конфигурации.
Java-класс бина практически аналогичен предыдущему.
Листинг 1: Файл бина
Это XML-файл конфигурации.
Листинг 2: Конфигурационный XML-файл.
Это файл для получения компонента из XML-файла конфигурации и вызова методов.
Листинг 3: Основной Java-файл.
Запустите приложение, и оно выдаст следующий результат.
Заключение
Автоматическая привязка требует осторожности. Не все привязки могут выполняться с помощью автоматического подключения. Оно не подходит для сложных привязок, и это следует учитывать.
Дайте знать, что вы думаете по данной теме материала в комментариях. За комментарии, отклики, подписки, лайки, дизлайки огромное вам спасибо!
Пожалуйста, опубликуйте свои комментарии по текущей теме материала. Мы крайне благодарны вам за ваши комментарии, подписки, лайки, дизлайки, отклики!